Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'fbdev-for-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev

Pull fbdev updates from Helge Deller:
"Three fbdev drivers (~8500 lines of code) removed. The Carillo Ranch
fbdev driver is for an Intel product which was never shipped, and for
the intelfb and the amba-clcd drivers the drm drivers can be used
instead.

The other code changes are minor: some fb_deferred_io flushing fixes,
imxfb margin fixes and stifb cleanups.

Summary:
- Remove intelfb fbdev driver (Thomas Zimmermann)
- Remove amba-clcd fbdev driver (Linus Walleij)
- Remove vmlfb Carillo Ranch fbdev driver (Matthew Wilcox)
- fb_deferred_io flushing fixes (Nam Cao)
- imxfb code fixes and cleanups (Dario Binacchi)
- stifb primary screen detection cleanups (Thomas Zimmermann)"

* tag 'fbdev-for-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev: (28 commits)
fbdev/intelfb: Remove driver
fbdev/hyperv_fb: Do not clear global screen_info
firmware/sysfb: Clear screen_info state after consuming it
fbdev/hyperv_fb: Remove firmware framebuffers with aperture helpers
drm/hyperv: Remove firmware framebuffers with aperture helper
fbdev/sis: Remove dependency on screen_info
video/logo: use %u format specifier for unsigned int values
video/sticore: Remove info field from STI struct
arch/parisc: Detect primary video device from device instance
fbdev/stifb: Allocate fb_info instance with framebuffer_alloc()
video/sticore: Store ROM device in STI struct
fbdev: flush deferred IO before closing
fbdev: flush deferred work in fb_deferred_io_fsync()
fbdev: amba-clcd: Delete the old CLCD driver
fbdev: Remove support for Carillo Ranch driver
fbdev: hgafb: fix kernel-doc comments
fbdev: mmp: Fix typo and wording in code comment
fbdev: fsl-diu-fb: Fix sparse warning due to virt_to_phys() prototype change
fbdev: imxfb: add '*/' on a separate line in block comment
fbdev: imxfb: use __func__ for function name
...

+208 -8708
-1
Documentation/fb/index.rst
··· 19 19 framebuffer 20 20 gxfb 21 21 intel810 22 - intelfb 23 22 internals 24 23 lxfb 25 24 matroxfb
-155
Documentation/fb/intelfb.rst
··· 1 - ============================================================= 2 - Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver 3 - ============================================================= 4 - 5 - A. Introduction 6 - =============== 7 - 8 - This is a framebuffer driver for various Intel 8xx/9xx compatible 9 - graphics devices. These would include: 10 - 11 - - Intel 830M 12 - - Intel 845G 13 - - Intel 852GM 14 - - Intel 855GM 15 - - Intel 865G 16 - - Intel 915G 17 - - Intel 915GM 18 - - Intel 945G 19 - - Intel 945GM 20 - - Intel 945GME 21 - - Intel 965G 22 - - Intel 965GM 23 - 24 - B. List of available options 25 - ============================= 26 - 27 - a. "video=intelfb" 28 - enables the intelfb driver 29 - 30 - Recommendation: required 31 - 32 - b. "mode=<xres>x<yres>[-<bpp>][@<refresh>]" 33 - select mode 34 - 35 - Recommendation: user preference 36 - (default = 1024x768-32@70) 37 - 38 - c. "vram=<value>" 39 - select amount of system RAM in MB to allocate for the video memory 40 - if not enough RAM was already allocated by the BIOS. 41 - 42 - Recommendation: 1 - 4 MB. 43 - (default = 4 MB) 44 - 45 - d. "voffset=<value>" 46 - select at what offset in MB of the logical memory to allocate the 47 - framebuffer memory. The intent is to avoid the memory blocks 48 - used by standard graphics applications (XFree86). Depending on your 49 - usage, adjust the value up or down, (0 for maximum usage, 63/127 MB 50 - for the least amount). Note, an arbitrary setting may conflict 51 - with XFree86. 52 - 53 - Recommendation: do not set 54 - (default = 48 MB) 55 - 56 - e. "accel" 57 - enable text acceleration. This can be enabled/reenabled anytime 58 - by using 'fbset -accel true/false'. 59 - 60 - Recommendation: enable 61 - (default = set) 62 - 63 - f. "hwcursor" 64 - enable cursor acceleration. 65 - 66 - Recommendation: enable 67 - (default = set) 68 - 69 - g. "mtrr" 70 - enable MTRR. This allows data transfers to the framebuffer memory 71 - to occur in bursts which can significantly increase performance. 72 - Not very helpful with the intel chips because of 'shared memory'. 73 - 74 - Recommendation: set 75 - (default = set) 76 - 77 - h. "fixed" 78 - disable mode switching. 79 - 80 - Recommendation: do not set 81 - (default = not set) 82 - 83 - The binary parameters can be unset with a "no" prefix, example "noaccel". 84 - The default parameter (not named) is the mode. 85 - 86 - C. Kernel booting 87 - ================= 88 - 89 - Separate each option/option-pair by commas (,) and the option from its value 90 - with an equals sign (=) as in the following:: 91 - 92 - video=intelfb:option1,option2=value2 93 - 94 - Sample Usage 95 - ------------ 96 - 97 - In /etc/lilo.conf, add the line:: 98 - 99 - append="video=intelfb:mode=800x600-32@75,accel,hwcursor,vram=8" 100 - 101 - This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The 102 - framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor 103 - will be enabled. 104 - 105 - Remarks 106 - ------- 107 - 108 - If setting this parameter doesn't work (you stay in a 80x25 text-mode), 109 - you might need to set the "vga=<mode>" parameter too - see vesafb.txt 110 - in this directory. 111 - 112 - 113 - D. Module options 114 - ================== 115 - 116 - The module parameters are essentially similar to the kernel 117 - parameters. The main difference is that you need to include a Boolean value 118 - (1 for TRUE, and 0 for FALSE) for those options which don't need a value. 119 - 120 - Example, to enable MTRR, include "mtrr=1". 121 - 122 - Sample Usage 123 - ------------ 124 - 125 - Using the same setup as described above, load the module like this:: 126 - 127 - modprobe intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1 128 - 129 - Or just add the following to a configuration file in /etc/modprobe.d/:: 130 - 131 - options intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1 132 - 133 - and just do a:: 134 - 135 - modprobe intelfb 136 - 137 - 138 - E. Acknowledgment: 139 - =================== 140 - 141 - 1. Geert Uytterhoeven - his excellent howto and the virtual 142 - framebuffer driver code made this possible. 143 - 144 - 2. Jeff Hartmann for his agpgart code. 145 - 146 - 3. David Dawes for his original kernel 2.4 code. 147 - 148 - 4. The X developers. Insights were provided just by reading the 149 - XFree86 source code. 150 - 151 - 5. Antonino A. Daplas for his inspiring i810fb driver. 152 - 153 - 6. Andrew Morton for his kernel patches maintenance. 154 - 155 - Sylvain
-1
Documentation/userspace-api/ioctl/ioctl-number.rst
··· 128 128 'F' all linux/fb.h conflict! 129 129 'F' 01-02 drivers/scsi/pmcraid.h conflict! 130 130 'F' 20 drivers/video/fsl-diu-fb.h conflict! 131 - 'F' 20 drivers/video/intelfb/intelfb.h conflict! 132 131 'F' 20 linux/ivtvfb.h conflict! 133 132 'F' 20 linux/matroxfb.h conflict! 134 133 'F' 20 drivers/video/aty/atyfb_base.c conflict!
-12
MAINTAINERS
··· 1693 1693 F: drivers/amba/ 1694 1694 F: include/linux/amba/bus.h 1695 1695 1696 - ARM PRIMECELL CLCD PL110 DRIVER 1697 - M: Russell King <linux@armlinux.org.uk> 1698 - S: Odd Fixes 1699 - F: drivers/video/fbdev/amba-clcd.* 1700 - 1701 1696 ARM PRIMECELL KMI PL050 DRIVER 1702 1697 M: Russell King <linux@armlinux.org.uk> 1703 1698 S: Odd Fixes ··· 10726 10731 S: Supported 10727 10732 F: drivers/infiniband/hw/irdma/ 10728 10733 F: include/uapi/rdma/irdma-abi.h 10729 - 10730 - INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) 10731 - M: Maik Broemme <mbroemme@libmpq.org> 10732 - L: linux-fbdev@vger.kernel.org 10733 - S: Maintained 10734 - F: Documentation/fb/intelfb.rst 10735 - F: drivers/video/fbdev/intelfb/ 10736 10734 10737 10735 INTEL GPIO DRIVERS 10738 10736 M: Andy Shevchenko <andy@kernel.org>
+1 -1
arch/parisc/video/fbdev.c
··· 21 21 return true; 22 22 23 23 /* return true if it's the default built-in framebuffer driver */ 24 - return (sti->info == info); 24 + return (sti->dev == info->device); 25 25 } 26 26 EXPORT_SYMBOL(fb_is_primary_device);
+1 -2
drivers/Makefile
··· 71 71 72 72 obj-$(CONFIG_CONNECTOR) += connector/ 73 73 74 - # i810fb and intelfb depend on char/agp/ 74 + # i810fb depends on char/agp/ 75 75 obj-$(CONFIG_FB_I810) += video/fbdev/i810/ 76 - obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/ 77 76 78 77 obj-$(CONFIG_PARPORT) += parport/ 79 78 obj-y += base/ block/ misc/ mfd/ nfc/
+13 -1
drivers/firmware/sysfb.c
··· 71 71 72 72 static __init int sysfb_init(void) 73 73 { 74 - struct screen_info *si = &screen_info; 74 + const struct screen_info *si = &screen_info; 75 75 struct simplefb_platform_data mode; 76 76 const char *name; 77 77 bool compatible; ··· 118 118 ret = platform_device_add(pd); 119 119 if (ret) 120 120 goto err; 121 + 122 + /* 123 + * The firmware framebuffer is now maintained by the created 124 + * device. Disable screen_info after we've consumed it. Prevents 125 + * invalid access during kexec reboots. 126 + * 127 + * TODO: Vgacon still relies on the global screen_info. Make 128 + * vgacon work with the platform device, so we can clear 129 + * the screen_info unconditionally. 130 + */ 131 + if (strcmp(name, "platform-framebuffer")) 132 + screen_info.orig_video_isVGA = 0; 121 133 122 134 goto unlock_mutex; 123 135 err:
+2 -6
drivers/gpu/drm/hyperv/hyperv_drm_drv.c
··· 7 7 #include <linux/hyperv.h> 8 8 #include <linux/module.h> 9 9 #include <linux/pci.h> 10 - #include <linux/screen_info.h> 11 10 12 11 #include <drm/drm_aperture.h> 13 12 #include <drm/drm_atomic_helper.h> ··· 72 73 struct drm_device *dev = &hv->dev; 73 74 int ret; 74 75 75 - if (IS_ENABLED(CONFIG_SYSFB)) 76 - drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, 77 - screen_info.lfb_size, 78 - &hyperv_driver); 79 - 80 76 hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024; 81 77 82 78 ret = vmbus_allocate_mmio(&hv->mem, hdev, 0, -1, hv->fb_size, 0x100000, ··· 123 129 drm_err(dev, "Failed to connect to vmbus.\n"); 124 130 goto err_hv_set_drv_data; 125 131 } 132 + 133 + drm_aperture_remove_framebuffers(&hyperv_driver); 126 134 127 135 ret = hyperv_setup_vram(hv, hdev); 128 136 if (ret)
-7
drivers/video/backlight/Kconfig
··· 235 235 If you have an HP Jornada 700 series, 236 236 say Y to include backlight control driver. 237 237 238 - config BACKLIGHT_CARILLO_RANCH 239 - tristate "Intel Carillo Ranch Backlight Driver" 240 - depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 241 - help 242 - If you have a Intel LE80578 (Carillo Ranch) say Y to enable the 243 - backlight driver. 244 - 245 238 config BACKLIGHT_PWM 246 239 tristate "Generic PWM based Backlight Driver" 247 240 depends on PWM
-1
drivers/video/backlight/Makefile
··· 25 25 obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o 26 26 obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o 27 27 obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o 28 - obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 29 28 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 30 29 obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o 31 30 obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
-264
drivers/video/backlight/cr_bllcd.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (c) Intel Corp. 2007. 4 - * All Rights Reserved. 5 - * 6 - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 7 - * develop this driver. 8 - * 9 - * This file is part of the Carillo Ranch video subsystem driver. 10 - * 11 - * Authors: 12 - * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> 13 - * Alan Hourihane <alanh-at-tungstengraphics-dot-com> 14 - */ 15 - 16 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 - 18 - #include <linux/module.h> 19 - #include <linux/kernel.h> 20 - #include <linux/init.h> 21 - #include <linux/platform_device.h> 22 - #include <linux/mutex.h> 23 - #include <linux/fb.h> 24 - #include <linux/backlight.h> 25 - #include <linux/lcd.h> 26 - #include <linux/pci.h> 27 - #include <linux/slab.h> 28 - 29 - /* The LVDS- and panel power controls sits on the 30 - * GPIO port of the ISA bridge. 31 - */ 32 - 33 - #define CRVML_DEVICE_LPC 0x27B8 34 - #define CRVML_REG_GPIOBAR 0x48 35 - #define CRVML_REG_GPIOEN 0x4C 36 - #define CRVML_GPIOEN_BIT (1 << 4) 37 - #define CRVML_PANEL_PORT 0x38 38 - #define CRVML_LVDS_ON 0x00000001 39 - #define CRVML_PANEL_ON 0x00000002 40 - #define CRVML_BACKLIGHT_OFF 0x00000004 41 - 42 - /* The PLL Clock register sits on Host bridge */ 43 - #define CRVML_DEVICE_MCH 0x5001 44 - #define CRVML_REG_MCHBAR 0x44 45 - #define CRVML_REG_MCHEN 0x54 46 - #define CRVML_MCHEN_BIT (1 << 28) 47 - #define CRVML_MCHMAP_SIZE 4096 48 - #define CRVML_REG_CLOCK 0xc3c 49 - #define CRVML_CLOCK_SHIFT 8 50 - #define CRVML_CLOCK_MASK 0x00000f00 51 - 52 - static struct pci_dev *lpc_dev; 53 - static u32 gpio_bar; 54 - 55 - struct cr_panel { 56 - struct backlight_device *cr_backlight_device; 57 - struct lcd_device *cr_lcd_device; 58 - }; 59 - 60 - static int cr_backlight_set_intensity(struct backlight_device *bd) 61 - { 62 - u32 addr = gpio_bar + CRVML_PANEL_PORT; 63 - u32 cur = inl(addr); 64 - 65 - if (backlight_get_brightness(bd) == 0) { 66 - /* OFF */ 67 - cur |= CRVML_BACKLIGHT_OFF; 68 - outl(cur, addr); 69 - } else { 70 - /* FULL ON */ 71 - cur &= ~CRVML_BACKLIGHT_OFF; 72 - outl(cur, addr); 73 - } 74 - 75 - return 0; 76 - } 77 - 78 - static int cr_backlight_get_intensity(struct backlight_device *bd) 79 - { 80 - u32 addr = gpio_bar + CRVML_PANEL_PORT; 81 - u32 cur = inl(addr); 82 - u8 intensity; 83 - 84 - if (cur & CRVML_BACKLIGHT_OFF) 85 - intensity = 0; 86 - else 87 - intensity = 1; 88 - 89 - return intensity; 90 - } 91 - 92 - static const struct backlight_ops cr_backlight_ops = { 93 - .get_brightness = cr_backlight_get_intensity, 94 - .update_status = cr_backlight_set_intensity, 95 - }; 96 - 97 - static void cr_panel_on(void) 98 - { 99 - u32 addr = gpio_bar + CRVML_PANEL_PORT; 100 - u32 cur = inl(addr); 101 - 102 - if (!(cur & CRVML_PANEL_ON)) { 103 - /* Make sure LVDS controller is down. */ 104 - if (cur & 0x00000001) { 105 - cur &= ~CRVML_LVDS_ON; 106 - outl(cur, addr); 107 - } 108 - /* Power up Panel */ 109 - schedule_timeout(HZ / 10); 110 - cur |= CRVML_PANEL_ON; 111 - outl(cur, addr); 112 - } 113 - 114 - /* Power up LVDS controller */ 115 - 116 - if (!(cur & CRVML_LVDS_ON)) { 117 - schedule_timeout(HZ / 10); 118 - outl(cur | CRVML_LVDS_ON, addr); 119 - } 120 - } 121 - 122 - static void cr_panel_off(void) 123 - { 124 - u32 addr = gpio_bar + CRVML_PANEL_PORT; 125 - u32 cur = inl(addr); 126 - 127 - /* Power down LVDS controller first to avoid high currents */ 128 - if (cur & CRVML_LVDS_ON) { 129 - cur &= ~CRVML_LVDS_ON; 130 - outl(cur, addr); 131 - } 132 - if (cur & CRVML_PANEL_ON) { 133 - schedule_timeout(HZ / 10); 134 - outl(cur & ~CRVML_PANEL_ON, addr); 135 - } 136 - } 137 - 138 - static int cr_lcd_set_power(struct lcd_device *ld, int power) 139 - { 140 - if (power == FB_BLANK_UNBLANK) 141 - cr_panel_on(); 142 - if (power == FB_BLANK_POWERDOWN) 143 - cr_panel_off(); 144 - 145 - return 0; 146 - } 147 - 148 - static struct lcd_ops cr_lcd_ops = { 149 - .set_power = cr_lcd_set_power, 150 - }; 151 - 152 - static int cr_backlight_probe(struct platform_device *pdev) 153 - { 154 - struct backlight_properties props; 155 - struct backlight_device *bdp; 156 - struct lcd_device *ldp; 157 - struct cr_panel *crp; 158 - u8 dev_en; 159 - 160 - lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 161 - CRVML_DEVICE_LPC, NULL); 162 - if (!lpc_dev) { 163 - pr_err("INTEL CARILLO RANCH LPC not found.\n"); 164 - return -ENODEV; 165 - } 166 - 167 - pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en); 168 - if (!(dev_en & CRVML_GPIOEN_BIT)) { 169 - pr_err("Carillo Ranch GPIO device was not enabled.\n"); 170 - pci_dev_put(lpc_dev); 171 - return -ENODEV; 172 - } 173 - 174 - memset(&props, 0, sizeof(struct backlight_properties)); 175 - props.type = BACKLIGHT_RAW; 176 - bdp = devm_backlight_device_register(&pdev->dev, "cr-backlight", 177 - &pdev->dev, NULL, &cr_backlight_ops, 178 - &props); 179 - if (IS_ERR(bdp)) { 180 - pci_dev_put(lpc_dev); 181 - return PTR_ERR(bdp); 182 - } 183 - 184 - ldp = devm_lcd_device_register(&pdev->dev, "cr-lcd", &pdev->dev, NULL, 185 - &cr_lcd_ops); 186 - if (IS_ERR(ldp)) { 187 - pci_dev_put(lpc_dev); 188 - return PTR_ERR(ldp); 189 - } 190 - 191 - pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR, 192 - &gpio_bar); 193 - gpio_bar &= ~0x3F; 194 - 195 - crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL); 196 - if (!crp) { 197 - pci_dev_put(lpc_dev); 198 - return -ENOMEM; 199 - } 200 - 201 - crp->cr_backlight_device = bdp; 202 - crp->cr_lcd_device = ldp; 203 - crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK; 204 - crp->cr_backlight_device->props.brightness = 0; 205 - cr_backlight_set_intensity(crp->cr_backlight_device); 206 - cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK); 207 - 208 - platform_set_drvdata(pdev, crp); 209 - 210 - return 0; 211 - } 212 - 213 - static void cr_backlight_remove(struct platform_device *pdev) 214 - { 215 - struct cr_panel *crp = platform_get_drvdata(pdev); 216 - 217 - crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN; 218 - crp->cr_backlight_device->props.brightness = 0; 219 - crp->cr_backlight_device->props.max_brightness = 0; 220 - cr_backlight_set_intensity(crp->cr_backlight_device); 221 - cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN); 222 - pci_dev_put(lpc_dev); 223 - } 224 - 225 - static struct platform_driver cr_backlight_driver = { 226 - .probe = cr_backlight_probe, 227 - .remove_new = cr_backlight_remove, 228 - .driver = { 229 - .name = "cr_backlight", 230 - }, 231 - }; 232 - 233 - static struct platform_device *crp; 234 - 235 - static int __init cr_backlight_init(void) 236 - { 237 - int ret = platform_driver_register(&cr_backlight_driver); 238 - 239 - if (ret) 240 - return ret; 241 - 242 - crp = platform_device_register_simple("cr_backlight", -1, NULL, 0); 243 - if (IS_ERR(crp)) { 244 - platform_driver_unregister(&cr_backlight_driver); 245 - return PTR_ERR(crp); 246 - } 247 - 248 - pr_info("Carillo Ranch Backlight Driver Initialized.\n"); 249 - 250 - return 0; 251 - } 252 - 253 - static void __exit cr_backlight_exit(void) 254 - { 255 - platform_device_unregister(crp); 256 - platform_driver_unregister(&cr_backlight_driver); 257 - } 258 - 259 - module_init(cr_backlight_init); 260 - module_exit(cr_backlight_exit); 261 - 262 - MODULE_AUTHOR("Tungsten Graphics Inc."); 263 - MODULE_DESCRIPTION("Carillo Ranch Backlight Driver"); 264 - MODULE_LICENSE("GPL");
-72
drivers/video/fbdev/Kconfig
··· 116 116 help 117 117 Support the Permedia2 FIFO disconnect feature. 118 118 119 - config FB_ARMCLCD 120 - tristate "ARM PrimeCell PL110 support" 121 - depends on ARM || ARM64 || COMPILE_TEST 122 - depends on FB && ARM_AMBA && HAS_IOMEM 123 - select FB_IOMEM_HELPERS 124 - select FB_MODE_HELPERS if OF 125 - select VIDEOMODE_HELPERS if OF 126 - select BACKLIGHT_CLASS_DEVICE if OF 127 - help 128 - This framebuffer device driver is for the ARM PrimeCell PL110 129 - Colour LCD controller. ARM PrimeCells provide the building 130 - blocks for System on a Chip devices. 131 - 132 - If you want to compile this as a module (=code which can be 133 - inserted into and removed from the running kernel), say M 134 - here and read <file:Documentation/kbuild/modules.rst>. The module 135 - will be called amba-clcd. 136 - 137 119 config FB_ACORN 138 120 bool "Acorn VIDC support" 139 121 depends on (FB = y) && ARM && ARCH_ACORN ··· 820 838 display information, especially for monitors with fickle timings. 821 839 822 840 If unsure, say Y. 823 - 824 - config FB_LE80578 825 - tristate "Intel LE80578 (Vermilion) support" 826 - depends on FB && PCI && X86 827 - select FB_IOMEM_HELPERS 828 - select FB_MODE_HELPERS 829 - select VIDEO_NOMODESET 830 - help 831 - This driver supports the LE80578 (Vermilion Range) chipset 832 - 833 - config FB_CARILLO_RANCH 834 - tristate "Intel Carillo Ranch support" 835 - depends on FB_LE80578 && FB && PCI && X86 836 - help 837 - This driver supports the LE80578 (Carillo Ranch) board 838 - 839 - config FB_INTEL 840 - tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" 841 - depends on FB && PCI && X86 && AGP_INTEL && EXPERT 842 - select FB_CFB_FILLRECT 843 - select FB_CFB_COPYAREA 844 - select FB_CFB_IMAGEBLIT 845 - select FB_IOMEM_FOPS 846 - select FB_MODE_HELPERS 847 - select BOOT_VESA_SUPPORT if FB_INTEL = y 848 - select VIDEO_NOMODESET 849 - depends on !DRM_I915 850 - help 851 - This driver supports the on-board graphics built in to the Intel 852 - 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. 853 - Say Y if you have and plan to use such a board. 854 - 855 - To make FB_INTEL=Y work you need to say AGP_INTEL=y too. 856 - 857 - To compile this driver as a module, choose M here: the 858 - module will be called intelfb. 859 - 860 - For more information, please read <file:Documentation/fb/intelfb.rst> 861 - 862 - config FB_INTEL_DEBUG 863 - bool "Intel driver Debug Messages" 864 - depends on FB_INTEL 865 - help 866 - Say Y here if you want the Intel driver to output all sorts 867 - of debugging information to provide to the maintainer when 868 - something goes wrong. 869 - 870 - config FB_INTEL_I2C 871 - bool "DDC/I2C for Intel framebuffer support" 872 - depends on FB_INTEL 873 - select FB_DDC 874 - default y 875 - help 876 - Say Y here if you want DDC/I2C support for your on-board Intel graphics. 877 841 878 842 config FB_MATROX 879 843 tristate "Matrox acceleration"
-2
drivers/video/fbdev/Makefile
··· 42 42 obj-$(CONFIG_FB_FM2) += fm2fb.o 43 43 obj-$(CONFIG_FB_VT8623) += vt8623fb.o 44 44 obj-$(CONFIG_FB_TRIDENT) += tridentfb.o 45 - obj-$(CONFIG_FB_LE80578) += vermilion/ 46 45 obj-$(CONFIG_FB_S3) += s3fb.o 47 46 obj-$(CONFIG_FB_ARK) += arkfb.o 48 47 obj-$(CONFIG_FB_STI) += stifb.o ··· 74 75 obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o 75 76 obj-$(CONFIG_FB_PVR2) += pvr2fb.o 76 77 obj-$(CONFIG_FB_VOODOO1) += sstfb.o 77 - obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o 78 78 obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o 79 79 obj-$(CONFIG_FB_68328) += 68328fb.o 80 80 obj-$(CONFIG_FB_GBE) += gbefb.o
-986
drivers/video/fbdev/amba-clcd.c
··· 1 - /* 2 - * linux/drivers/video/amba-clcd.c 3 - * 4 - * Copyright (C) 2001 ARM Limited, by David A Rusling 5 - * Updated to 2.5, Deep Blue Solutions Ltd. 6 - * 7 - * This file is subject to the terms and conditions of the GNU General Public 8 - * License. See the file COPYING in the main directory of this archive 9 - * for more details. 10 - * 11 - * ARM PrimeCell PL110 Color LCD Controller 12 - */ 13 - #include <linux/amba/bus.h> 14 - #include <linux/amba/clcd.h> 15 - #include <linux/backlight.h> 16 - #include <linux/clk.h> 17 - #include <linux/delay.h> 18 - #include <linux/dma-mapping.h> 19 - #include <linux/fb.h> 20 - #include <linux/init.h> 21 - #include <linux/ioport.h> 22 - #include <linux/list.h> 23 - #include <linux/mm.h> 24 - #include <linux/module.h> 25 - #include <linux/of_address.h> 26 - #include <linux/of_graph.h> 27 - #include <linux/slab.h> 28 - #include <linux/string.h> 29 - #include <video/display_timing.h> 30 - #include <video/of_display_timing.h> 31 - #include <video/videomode.h> 32 - 33 - #define to_clcd(info) container_of(info, struct clcd_fb, fb) 34 - 35 - /* This is limited to 16 characters when displayed by X startup */ 36 - static const char *clcd_name = "CLCD FB"; 37 - 38 - static inline void clcdfb_set_start(struct clcd_fb *fb) 39 - { 40 - unsigned long ustart = fb->fb.fix.smem_start; 41 - unsigned long lstart; 42 - 43 - ustart += fb->fb.var.yoffset * fb->fb.fix.line_length; 44 - lstart = ustart + fb->fb.var.yres * fb->fb.fix.line_length / 2; 45 - 46 - writel(ustart, fb->regs + CLCD_UBAS); 47 - writel(lstart, fb->regs + CLCD_LBAS); 48 - } 49 - 50 - static void clcdfb_disable(struct clcd_fb *fb) 51 - { 52 - u32 val; 53 - 54 - if (fb->board->disable) 55 - fb->board->disable(fb); 56 - 57 - if (fb->panel->backlight) { 58 - fb->panel->backlight->props.power = FB_BLANK_POWERDOWN; 59 - backlight_update_status(fb->panel->backlight); 60 - } 61 - 62 - val = readl(fb->regs + fb->off_cntl); 63 - if (val & CNTL_LCDPWR) { 64 - val &= ~CNTL_LCDPWR; 65 - writel(val, fb->regs + fb->off_cntl); 66 - 67 - msleep(20); 68 - } 69 - if (val & CNTL_LCDEN) { 70 - val &= ~CNTL_LCDEN; 71 - writel(val, fb->regs + fb->off_cntl); 72 - } 73 - 74 - /* 75 - * Disable CLCD clock source. 76 - */ 77 - if (fb->clk_enabled) { 78 - fb->clk_enabled = false; 79 - clk_disable(fb->clk); 80 - } 81 - } 82 - 83 - static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) 84 - { 85 - /* 86 - * Enable the CLCD clock source. 87 - */ 88 - if (!fb->clk_enabled) { 89 - fb->clk_enabled = true; 90 - clk_enable(fb->clk); 91 - } 92 - 93 - /* 94 - * Bring up by first enabling.. 95 - */ 96 - cntl |= CNTL_LCDEN; 97 - writel(cntl, fb->regs + fb->off_cntl); 98 - 99 - msleep(20); 100 - 101 - /* 102 - * and now apply power. 103 - */ 104 - cntl |= CNTL_LCDPWR; 105 - writel(cntl, fb->regs + fb->off_cntl); 106 - 107 - /* 108 - * Turn on backlight 109 - */ 110 - if (fb->panel->backlight) { 111 - fb->panel->backlight->props.power = FB_BLANK_UNBLANK; 112 - backlight_update_status(fb->panel->backlight); 113 - } 114 - 115 - /* 116 - * finally, enable the interface. 117 - */ 118 - if (fb->board->enable) 119 - fb->board->enable(fb); 120 - } 121 - 122 - static int 123 - clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) 124 - { 125 - u32 caps; 126 - int ret = 0; 127 - 128 - if (fb->panel->caps && fb->board->caps) 129 - caps = fb->panel->caps & fb->board->caps; 130 - else { 131 - /* Old way of specifying what can be used */ 132 - caps = fb->panel->cntl & CNTL_BGR ? 133 - CLCD_CAP_BGR : CLCD_CAP_RGB; 134 - /* But mask out 444 modes as they weren't supported */ 135 - caps &= ~CLCD_CAP_444; 136 - } 137 - 138 - /* Only TFT panels can do RGB888/BGR888 */ 139 - if (!(fb->panel->cntl & CNTL_LCDTFT)) 140 - caps &= ~CLCD_CAP_888; 141 - 142 - memset(&var->transp, 0, sizeof(var->transp)); 143 - 144 - var->red.msb_right = 0; 145 - var->green.msb_right = 0; 146 - var->blue.msb_right = 0; 147 - 148 - switch (var->bits_per_pixel) { 149 - case 1: 150 - case 2: 151 - case 4: 152 - case 8: 153 - /* If we can't do 5551, reject */ 154 - caps &= CLCD_CAP_5551; 155 - if (!caps) { 156 - ret = -EINVAL; 157 - break; 158 - } 159 - 160 - var->red.length = var->bits_per_pixel; 161 - var->red.offset = 0; 162 - var->green.length = var->bits_per_pixel; 163 - var->green.offset = 0; 164 - var->blue.length = var->bits_per_pixel; 165 - var->blue.offset = 0; 166 - break; 167 - 168 - case 16: 169 - /* If we can't do 444, 5551 or 565, reject */ 170 - if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) { 171 - ret = -EINVAL; 172 - break; 173 - } 174 - 175 - /* 176 - * Green length can be 4, 5 or 6 depending whether 177 - * we're operating in 444, 5551 or 565 mode. 178 - */ 179 - if (var->green.length == 4 && caps & CLCD_CAP_444) 180 - caps &= CLCD_CAP_444; 181 - if (var->green.length == 5 && caps & CLCD_CAP_5551) 182 - caps &= CLCD_CAP_5551; 183 - else if (var->green.length == 6 && caps & CLCD_CAP_565) 184 - caps &= CLCD_CAP_565; 185 - else { 186 - /* 187 - * PL110 officially only supports RGB555, 188 - * but may be wired up to allow RGB565. 189 - */ 190 - if (caps & CLCD_CAP_565) { 191 - var->green.length = 6; 192 - caps &= CLCD_CAP_565; 193 - } else if (caps & CLCD_CAP_5551) { 194 - var->green.length = 5; 195 - caps &= CLCD_CAP_5551; 196 - } else { 197 - var->green.length = 4; 198 - caps &= CLCD_CAP_444; 199 - } 200 - } 201 - 202 - if (var->green.length >= 5) { 203 - var->red.length = 5; 204 - var->blue.length = 5; 205 - } else { 206 - var->red.length = 4; 207 - var->blue.length = 4; 208 - } 209 - break; 210 - case 32: 211 - /* If we can't do 888, reject */ 212 - caps &= CLCD_CAP_888; 213 - if (!caps) { 214 - ret = -EINVAL; 215 - break; 216 - } 217 - 218 - var->red.length = 8; 219 - var->green.length = 8; 220 - var->blue.length = 8; 221 - break; 222 - default: 223 - ret = -EINVAL; 224 - break; 225 - } 226 - 227 - /* 228 - * >= 16bpp displays have separate colour component bitfields 229 - * encoded in the pixel data. Calculate their position from 230 - * the bitfield length defined above. 231 - */ 232 - if (ret == 0 && var->bits_per_pixel >= 16) { 233 - bool bgr, rgb; 234 - 235 - bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0; 236 - rgb = caps & CLCD_CAP_RGB && var->red.offset == 0; 237 - 238 - if (!bgr && !rgb) 239 - /* 240 - * The requested format was not possible, try just 241 - * our capabilities. One of BGR or RGB must be 242 - * supported. 243 - */ 244 - bgr = caps & CLCD_CAP_BGR; 245 - 246 - if (bgr) { 247 - var->blue.offset = 0; 248 - var->green.offset = var->blue.offset + var->blue.length; 249 - var->red.offset = var->green.offset + var->green.length; 250 - } else { 251 - var->red.offset = 0; 252 - var->green.offset = var->red.offset + var->red.length; 253 - var->blue.offset = var->green.offset + var->green.length; 254 - } 255 - } 256 - 257 - return ret; 258 - } 259 - 260 - static int clcdfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 261 - { 262 - struct clcd_fb *fb = to_clcd(info); 263 - int ret = -EINVAL; 264 - 265 - if (fb->board->check) 266 - ret = fb->board->check(fb, var); 267 - 268 - if (ret == 0 && 269 - var->xres_virtual * var->bits_per_pixel / 8 * 270 - var->yres_virtual > fb->fb.fix.smem_len) 271 - ret = -EINVAL; 272 - 273 - if (ret == 0) 274 - ret = clcdfb_set_bitfields(fb, var); 275 - 276 - return ret; 277 - } 278 - 279 - static int clcdfb_set_par(struct fb_info *info) 280 - { 281 - struct clcd_fb *fb = to_clcd(info); 282 - struct clcd_regs regs; 283 - 284 - fb->fb.fix.line_length = fb->fb.var.xres_virtual * 285 - fb->fb.var.bits_per_pixel / 8; 286 - 287 - if (fb->fb.var.bits_per_pixel <= 8) 288 - fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; 289 - else 290 - fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; 291 - 292 - fb->board->decode(fb, &regs); 293 - 294 - clcdfb_disable(fb); 295 - 296 - writel(regs.tim0, fb->regs + CLCD_TIM0); 297 - writel(regs.tim1, fb->regs + CLCD_TIM1); 298 - writel(regs.tim2, fb->regs + CLCD_TIM2); 299 - writel(regs.tim3, fb->regs + CLCD_TIM3); 300 - 301 - clcdfb_set_start(fb); 302 - 303 - clk_set_rate(fb->clk, (1000000000 / regs.pixclock) * 1000); 304 - 305 - fb->clcd_cntl = regs.cntl; 306 - 307 - clcdfb_enable(fb, regs.cntl); 308 - 309 - #ifdef DEBUG 310 - printk(KERN_INFO 311 - "CLCD: Registers set to\n" 312 - " %08x %08x %08x %08x\n" 313 - " %08x %08x %08x %08x\n", 314 - readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), 315 - readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), 316 - readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), 317 - readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl)); 318 - #endif 319 - 320 - return 0; 321 - } 322 - 323 - static inline u32 convert_bitfield(int val, struct fb_bitfield *bf) 324 - { 325 - unsigned int mask = (1 << bf->length) - 1; 326 - 327 - return (val >> (16 - bf->length) & mask) << bf->offset; 328 - } 329 - 330 - /* 331 - * Set a single color register. The values supplied have a 16 bit 332 - * magnitude. Return != 0 for invalid regno. 333 - */ 334 - static int 335 - clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, 336 - unsigned int blue, unsigned int transp, struct fb_info *info) 337 - { 338 - struct clcd_fb *fb = to_clcd(info); 339 - 340 - if (regno < 16) 341 - fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | 342 - convert_bitfield(blue, &fb->fb.var.blue) | 343 - convert_bitfield(green, &fb->fb.var.green) | 344 - convert_bitfield(red, &fb->fb.var.red); 345 - 346 - if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) { 347 - int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3); 348 - u32 val, mask, newval; 349 - 350 - newval = (red >> 11) & 0x001f; 351 - newval |= (green >> 6) & 0x03e0; 352 - newval |= (blue >> 1) & 0x7c00; 353 - 354 - /* 355 - * 3.2.11: if we're configured for big endian 356 - * byte order, the palette entries are swapped. 357 - */ 358 - if (fb->clcd_cntl & CNTL_BEBO) 359 - regno ^= 1; 360 - 361 - if (regno & 1) { 362 - newval <<= 16; 363 - mask = 0x0000ffff; 364 - } else { 365 - mask = 0xffff0000; 366 - } 367 - 368 - val = readl(fb->regs + hw_reg) & mask; 369 - writel(val | newval, fb->regs + hw_reg); 370 - } 371 - 372 - return regno > 255; 373 - } 374 - 375 - /* 376 - * Blank the screen if blank_mode != 0, else unblank. If blank == NULL 377 - * then the caller blanks by setting the CLUT (Color Look Up Table) to all 378 - * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due 379 - * to e.g. a video mode which doesn't support it. Implements VESA suspend 380 - * and powerdown modes on hardware that supports disabling hsync/vsync: 381 - * blank_mode == 2: suspend vsync 382 - * blank_mode == 3: suspend hsync 383 - * blank_mode == 4: powerdown 384 - */ 385 - static int clcdfb_blank(int blank_mode, struct fb_info *info) 386 - { 387 - struct clcd_fb *fb = to_clcd(info); 388 - 389 - if (blank_mode != 0) { 390 - clcdfb_disable(fb); 391 - } else { 392 - clcdfb_enable(fb, fb->clcd_cntl); 393 - } 394 - return 0; 395 - } 396 - 397 - static int clcdfb_mmap(struct fb_info *info, 398 - struct vm_area_struct *vma) 399 - { 400 - struct clcd_fb *fb = to_clcd(info); 401 - unsigned long len, off = vma->vm_pgoff << PAGE_SHIFT; 402 - int ret = -EINVAL; 403 - 404 - len = info->fix.smem_len; 405 - 406 - if (off <= len && vma->vm_end - vma->vm_start <= len - off && 407 - fb->board->mmap) 408 - ret = fb->board->mmap(fb, vma); 409 - 410 - return ret; 411 - } 412 - 413 - static const struct fb_ops clcdfb_ops = { 414 - .owner = THIS_MODULE, 415 - __FB_DEFAULT_IOMEM_OPS_RDWR, 416 - .fb_check_var = clcdfb_check_var, 417 - .fb_set_par = clcdfb_set_par, 418 - .fb_setcolreg = clcdfb_setcolreg, 419 - .fb_blank = clcdfb_blank, 420 - __FB_DEFAULT_IOMEM_OPS_DRAW, 421 - .fb_mmap = clcdfb_mmap, 422 - }; 423 - 424 - static int clcdfb_register(struct clcd_fb *fb) 425 - { 426 - int ret; 427 - 428 - /* 429 - * ARM PL111 always has IENB at 0x1c; it's only PL110 430 - * which is reversed on some platforms. 431 - */ 432 - if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) { 433 - fb->off_ienb = CLCD_PL111_IENB; 434 - fb->off_cntl = CLCD_PL111_CNTL; 435 - } else { 436 - fb->off_ienb = CLCD_PL110_IENB; 437 - fb->off_cntl = CLCD_PL110_CNTL; 438 - } 439 - 440 - fb->clk = clk_get(&fb->dev->dev, NULL); 441 - if (IS_ERR(fb->clk)) { 442 - ret = PTR_ERR(fb->clk); 443 - goto out; 444 - } 445 - 446 - ret = clk_prepare(fb->clk); 447 - if (ret) 448 - goto free_clk; 449 - 450 - fb->fb.device = &fb->dev->dev; 451 - 452 - fb->fb.fix.mmio_start = fb->dev->res.start; 453 - fb->fb.fix.mmio_len = resource_size(&fb->dev->res); 454 - 455 - fb->regs = ioremap(fb->fb.fix.mmio_start, fb->fb.fix.mmio_len); 456 - if (!fb->regs) { 457 - printk(KERN_ERR "CLCD: unable to remap registers\n"); 458 - ret = -ENOMEM; 459 - goto clk_unprep; 460 - } 461 - 462 - fb->fb.fbops = &clcdfb_ops; 463 - fb->fb.pseudo_palette = fb->cmap; 464 - 465 - strncpy(fb->fb.fix.id, clcd_name, sizeof(fb->fb.fix.id)); 466 - fb->fb.fix.type = FB_TYPE_PACKED_PIXELS; 467 - fb->fb.fix.type_aux = 0; 468 - fb->fb.fix.xpanstep = 0; 469 - fb->fb.fix.ypanstep = 0; 470 - fb->fb.fix.ywrapstep = 0; 471 - fb->fb.fix.accel = FB_ACCEL_NONE; 472 - 473 - fb->fb.var.xres = fb->panel->mode.xres; 474 - fb->fb.var.yres = fb->panel->mode.yres; 475 - fb->fb.var.xres_virtual = fb->panel->mode.xres; 476 - fb->fb.var.yres_virtual = fb->panel->mode.yres; 477 - fb->fb.var.bits_per_pixel = fb->panel->bpp; 478 - fb->fb.var.grayscale = fb->panel->grayscale; 479 - fb->fb.var.pixclock = fb->panel->mode.pixclock; 480 - fb->fb.var.left_margin = fb->panel->mode.left_margin; 481 - fb->fb.var.right_margin = fb->panel->mode.right_margin; 482 - fb->fb.var.upper_margin = fb->panel->mode.upper_margin; 483 - fb->fb.var.lower_margin = fb->panel->mode.lower_margin; 484 - fb->fb.var.hsync_len = fb->panel->mode.hsync_len; 485 - fb->fb.var.vsync_len = fb->panel->mode.vsync_len; 486 - fb->fb.var.sync = fb->panel->mode.sync; 487 - fb->fb.var.vmode = fb->panel->mode.vmode; 488 - fb->fb.var.activate = FB_ACTIVATE_NOW; 489 - fb->fb.var.nonstd = 0; 490 - fb->fb.var.height = fb->panel->height; 491 - fb->fb.var.width = fb->panel->width; 492 - fb->fb.var.accel_flags = 0; 493 - 494 - fb->fb.monspecs.hfmin = 0; 495 - fb->fb.monspecs.hfmax = 100000; 496 - fb->fb.monspecs.vfmin = 0; 497 - fb->fb.monspecs.vfmax = 400; 498 - fb->fb.monspecs.dclkmin = 1000000; 499 - fb->fb.monspecs.dclkmax = 100000000; 500 - 501 - /* 502 - * Make sure that the bitfields are set appropriately. 503 - */ 504 - clcdfb_set_bitfields(fb, &fb->fb.var); 505 - 506 - /* 507 - * Allocate colourmap. 508 - */ 509 - ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0); 510 - if (ret) 511 - goto unmap; 512 - 513 - /* 514 - * Ensure interrupts are disabled. 515 - */ 516 - writel(0, fb->regs + fb->off_ienb); 517 - 518 - fb_set_var(&fb->fb, &fb->fb.var); 519 - 520 - dev_info(&fb->dev->dev, "%s hardware, %s display\n", 521 - fb->board->name, fb->panel->mode.name); 522 - 523 - ret = register_framebuffer(&fb->fb); 524 - if (ret == 0) 525 - goto out; 526 - 527 - printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret); 528 - 529 - fb_dealloc_cmap(&fb->fb.cmap); 530 - unmap: 531 - iounmap(fb->regs); 532 - clk_unprep: 533 - clk_unprepare(fb->clk); 534 - free_clk: 535 - clk_put(fb->clk); 536 - out: 537 - return ret; 538 - } 539 - 540 - #ifdef CONFIG_OF 541 - static int clcdfb_of_get_dpi_panel_mode(struct device_node *node, 542 - struct clcd_panel *clcd_panel) 543 - { 544 - int err; 545 - struct display_timing timing; 546 - struct videomode video; 547 - 548 - err = of_get_display_timing(node, "panel-timing", &timing); 549 - if (err) { 550 - pr_err("%pOF: problems parsing panel-timing (%d)\n", node, err); 551 - return err; 552 - } 553 - 554 - videomode_from_timing(&timing, &video); 555 - 556 - err = fb_videomode_from_videomode(&video, &clcd_panel->mode); 557 - if (err) 558 - return err; 559 - 560 - /* Set up some inversion flags */ 561 - if (timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) 562 - clcd_panel->tim2 |= TIM2_IPC; 563 - else if (!(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)) 564 - /* 565 - * To preserve backwards compatibility, the IPC (inverted 566 - * pixel clock) flag needs to be set on any display that 567 - * doesn't explicitly specify that the pixel clock is 568 - * active on the negative or positive edge. 569 - */ 570 - clcd_panel->tim2 |= TIM2_IPC; 571 - 572 - if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW) 573 - clcd_panel->tim2 |= TIM2_IHS; 574 - 575 - if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW) 576 - clcd_panel->tim2 |= TIM2_IVS; 577 - 578 - if (timing.flags & DISPLAY_FLAGS_DE_LOW) 579 - clcd_panel->tim2 |= TIM2_IOE; 580 - 581 - return 0; 582 - } 583 - 584 - static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode) 585 - { 586 - return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres, 587 - mode->refresh); 588 - } 589 - 590 - static int clcdfb_of_get_backlight(struct device *dev, 591 - struct clcd_panel *clcd_panel) 592 - { 593 - struct backlight_device *backlight; 594 - 595 - /* Look up the optional backlight device */ 596 - backlight = devm_of_find_backlight(dev); 597 - if (IS_ERR(backlight)) 598 - return PTR_ERR(backlight); 599 - 600 - clcd_panel->backlight = backlight; 601 - return 0; 602 - } 603 - 604 - static int clcdfb_of_get_mode(struct device *dev, struct device_node *panel, 605 - struct clcd_panel *clcd_panel) 606 - { 607 - int err; 608 - struct fb_videomode *mode; 609 - char *name; 610 - int len; 611 - 612 - /* Only directly connected DPI panels supported for now */ 613 - if (of_device_is_compatible(panel, "panel-dpi")) 614 - err = clcdfb_of_get_dpi_panel_mode(panel, clcd_panel); 615 - else 616 - err = -ENOENT; 617 - if (err) 618 - return err; 619 - mode = &clcd_panel->mode; 620 - 621 - len = clcdfb_snprintf_mode(NULL, 0, mode); 622 - name = devm_kzalloc(dev, len + 1, GFP_KERNEL); 623 - if (!name) 624 - return -ENOMEM; 625 - 626 - clcdfb_snprintf_mode(name, len + 1, mode); 627 - mode->name = name; 628 - 629 - return 0; 630 - } 631 - 632 - static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0) 633 - { 634 - static struct { 635 - unsigned int part; 636 - u32 r0, g0, b0; 637 - u32 caps; 638 - } panels[] = { 639 - { 0x110, 1, 7, 13, CLCD_CAP_5551 }, 640 - { 0x110, 0, 8, 16, CLCD_CAP_888 }, 641 - { 0x110, 16, 8, 0, CLCD_CAP_888 }, 642 - { 0x111, 4, 14, 20, CLCD_CAP_444 }, 643 - { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 }, 644 - { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 | 645 - CLCD_CAP_565 }, 646 - { 0x111, 0, 8, 16, CLCD_CAP_444 | CLCD_CAP_5551 | 647 - CLCD_CAP_565 | CLCD_CAP_888 }, 648 - }; 649 - int i; 650 - 651 - /* Bypass pixel clock divider */ 652 - fb->panel->tim2 |= TIM2_BCD; 653 - 654 - /* TFT display, vert. comp. interrupt at the start of the back porch */ 655 - fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1); 656 - 657 - fb->panel->caps = 0; 658 - 659 - /* Match the setup with known variants */ 660 - for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) { 661 - if (amba_part(fb->dev) != panels[i].part) 662 - continue; 663 - if (g0 != panels[i].g0) 664 - continue; 665 - if (r0 == panels[i].r0 && b0 == panels[i].b0) 666 - fb->panel->caps = panels[i].caps; 667 - } 668 - 669 - /* 670 - * If we actually physically connected the R lines to B and 671 - * vice versa 672 - */ 673 - if (r0 != 0 && b0 == 0) 674 - fb->panel->bgr_connection = true; 675 - 676 - return fb->panel->caps ? 0 : -EINVAL; 677 - } 678 - 679 - static int clcdfb_of_init_display(struct clcd_fb *fb) 680 - { 681 - struct device_node *endpoint, *panel; 682 - int err; 683 - unsigned int bpp; 684 - u32 max_bandwidth; 685 - u32 tft_r0b0g0[3]; 686 - 687 - fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL); 688 - if (!fb->panel) 689 - return -ENOMEM; 690 - 691 - /* 692 - * Fetch the panel endpoint. 693 - */ 694 - endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL); 695 - if (!endpoint) 696 - return -ENODEV; 697 - 698 - panel = of_graph_get_remote_port_parent(endpoint); 699 - if (!panel) { 700 - err = -ENODEV; 701 - goto out_endpoint_put; 702 - } 703 - 704 - err = clcdfb_of_get_backlight(&fb->dev->dev, fb->panel); 705 - if (err) 706 - goto out_panel_put; 707 - 708 - err = clcdfb_of_get_mode(&fb->dev->dev, panel, fb->panel); 709 - if (err) 710 - goto out_panel_put; 711 - 712 - err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", 713 - &max_bandwidth); 714 - if (!err) { 715 - /* 716 - * max_bandwidth is in bytes per second and pixclock in 717 - * pico-seconds, so the maximum allowed bits per pixel is 718 - * 8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000) 719 - * Rearrange this calculation to avoid overflow and then ensure 720 - * result is a valid format. 721 - */ 722 - bpp = max_bandwidth / (1000 / 8) 723 - / PICOS2KHZ(fb->panel->mode.pixclock); 724 - bpp = rounddown_pow_of_two(bpp); 725 - if (bpp > 32) 726 - bpp = 32; 727 - } else 728 - bpp = 32; 729 - fb->panel->bpp = bpp; 730 - 731 - #ifdef CONFIG_CPU_BIG_ENDIAN 732 - fb->panel->cntl |= CNTL_BEBO; 733 - #endif 734 - fb->panel->width = -1; 735 - fb->panel->height = -1; 736 - 737 - if (of_property_read_u32_array(endpoint, 738 - "arm,pl11x,tft-r0g0b0-pads", 739 - tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0) { 740 - err = -ENOENT; 741 - goto out_panel_put; 742 - } 743 - 744 - of_node_put(panel); 745 - of_node_put(endpoint); 746 - 747 - return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0], 748 - tft_r0b0g0[1], tft_r0b0g0[2]); 749 - out_panel_put: 750 - of_node_put(panel); 751 - out_endpoint_put: 752 - of_node_put(endpoint); 753 - return err; 754 - } 755 - 756 - static int clcdfb_of_vram_setup(struct clcd_fb *fb) 757 - { 758 - int err; 759 - struct device_node *memory; 760 - u64 size; 761 - 762 - err = clcdfb_of_init_display(fb); 763 - if (err) 764 - return err; 765 - 766 - memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0); 767 - if (!memory) 768 - return -ENODEV; 769 - 770 - fb->fb.screen_base = of_iomap(memory, 0); 771 - if (!fb->fb.screen_base) { 772 - of_node_put(memory); 773 - return -ENOMEM; 774 - } 775 - 776 - fb->fb.fix.smem_start = of_translate_address(memory, 777 - of_get_address(memory, 0, &size, NULL)); 778 - fb->fb.fix.smem_len = size; 779 - of_node_put(memory); 780 - 781 - return 0; 782 - } 783 - 784 - static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) 785 - { 786 - unsigned long off, user_size, kernel_size; 787 - 788 - 789 - off = vma->vm_pgoff << PAGE_SHIFT; 790 - user_size = vma->vm_end - vma->vm_start; 791 - kernel_size = fb->fb.fix.smem_len; 792 - 793 - if (off >= kernel_size || user_size > (kernel_size - off)) 794 - return -ENXIO; 795 - 796 - return remap_pfn_range(vma, vma->vm_start, 797 - __phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff, 798 - user_size, 799 - pgprot_writecombine(vma->vm_page_prot)); 800 - } 801 - 802 - static void clcdfb_of_vram_remove(struct clcd_fb *fb) 803 - { 804 - iounmap(fb->fb.screen_base); 805 - } 806 - 807 - static int clcdfb_of_dma_setup(struct clcd_fb *fb) 808 - { 809 - unsigned long framesize; 810 - dma_addr_t dma; 811 - int err; 812 - 813 - err = clcdfb_of_init_display(fb); 814 - if (err) 815 - return err; 816 - 817 - framesize = PAGE_ALIGN(fb->panel->mode.xres * fb->panel->mode.yres * 818 - fb->panel->bpp / 8); 819 - fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize, 820 - &dma, GFP_KERNEL); 821 - if (!fb->fb.screen_base) 822 - return -ENOMEM; 823 - 824 - fb->fb.fix.smem_start = dma; 825 - fb->fb.fix.smem_len = framesize; 826 - 827 - return 0; 828 - } 829 - 830 - static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) 831 - { 832 - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); 833 - 834 - return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base, 835 - fb->fb.fix.smem_start, fb->fb.fix.smem_len); 836 - } 837 - 838 - static void clcdfb_of_dma_remove(struct clcd_fb *fb) 839 - { 840 - dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len, 841 - fb->fb.screen_base, fb->fb.fix.smem_start); 842 - } 843 - 844 - static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev) 845 - { 846 - struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board), 847 - GFP_KERNEL); 848 - struct device_node *node = dev->dev.of_node; 849 - 850 - if (!board) 851 - return NULL; 852 - 853 - board->name = of_node_full_name(node); 854 - board->caps = CLCD_CAP_ALL; 855 - board->check = clcdfb_check; 856 - board->decode = clcdfb_decode; 857 - if (of_property_present(node, "memory-region")) { 858 - board->setup = clcdfb_of_vram_setup; 859 - board->mmap = clcdfb_of_vram_mmap; 860 - board->remove = clcdfb_of_vram_remove; 861 - } else { 862 - board->setup = clcdfb_of_dma_setup; 863 - board->mmap = clcdfb_of_dma_mmap; 864 - board->remove = clcdfb_of_dma_remove; 865 - } 866 - 867 - return board; 868 - } 869 - #else 870 - static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev) 871 - { 872 - return NULL; 873 - } 874 - #endif 875 - 876 - static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) 877 - { 878 - struct clcd_board *board = dev_get_platdata(&dev->dev); 879 - struct clcd_fb *fb; 880 - int ret; 881 - 882 - if (!board) 883 - board = clcdfb_of_get_board(dev); 884 - 885 - if (!board) 886 - return -EINVAL; 887 - 888 - ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); 889 - if (ret) 890 - goto out; 891 - 892 - ret = amba_request_regions(dev, NULL); 893 - if (ret) { 894 - printk(KERN_ERR "CLCD: unable to reserve regs region\n"); 895 - goto out; 896 - } 897 - 898 - fb = kzalloc(sizeof(*fb), GFP_KERNEL); 899 - if (!fb) { 900 - ret = -ENOMEM; 901 - goto free_region; 902 - } 903 - 904 - fb->dev = dev; 905 - fb->board = board; 906 - 907 - dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n", 908 - amba_part(dev), amba_manf(dev), amba_rev(dev), 909 - (unsigned long long)dev->res.start); 910 - 911 - ret = fb->board->setup(fb); 912 - if (ret) 913 - goto free_fb; 914 - 915 - ret = clcdfb_register(fb); 916 - if (ret == 0) { 917 - amba_set_drvdata(dev, fb); 918 - goto out; 919 - } 920 - 921 - fb->board->remove(fb); 922 - free_fb: 923 - kfree(fb); 924 - free_region: 925 - amba_release_regions(dev); 926 - out: 927 - return ret; 928 - } 929 - 930 - static void clcdfb_remove(struct amba_device *dev) 931 - { 932 - struct clcd_fb *fb = amba_get_drvdata(dev); 933 - 934 - clcdfb_disable(fb); 935 - unregister_framebuffer(&fb->fb); 936 - if (fb->fb.cmap.len) 937 - fb_dealloc_cmap(&fb->fb.cmap); 938 - iounmap(fb->regs); 939 - clk_unprepare(fb->clk); 940 - clk_put(fb->clk); 941 - 942 - fb->board->remove(fb); 943 - 944 - kfree(fb); 945 - 946 - amba_release_regions(dev); 947 - } 948 - 949 - static const struct amba_id clcdfb_id_table[] = { 950 - { 951 - .id = 0x00041110, 952 - .mask = 0x000ffffe, 953 - }, 954 - { 0, 0 }, 955 - }; 956 - 957 - MODULE_DEVICE_TABLE(amba, clcdfb_id_table); 958 - 959 - static struct amba_driver clcd_driver = { 960 - .drv = { 961 - .name = "clcd-pl11x", 962 - }, 963 - .probe = clcdfb_probe, 964 - .remove = clcdfb_remove, 965 - .id_table = clcdfb_id_table, 966 - }; 967 - 968 - static int __init amba_clcdfb_init(void) 969 - { 970 - if (fb_get_options("ambafb", NULL)) 971 - return -ENODEV; 972 - 973 - return amba_driver_register(&clcd_driver); 974 - } 975 - 976 - module_init(amba_clcdfb_init); 977 - 978 - static void __exit amba_clcdfb_exit(void) 979 - { 980 - amba_driver_unregister(&clcd_driver); 981 - } 982 - 983 - module_exit(amba_clcdfb_exit); 984 - 985 - MODULE_DESCRIPTION("ARM PrimeCell PL110 CLCD core driver"); 986 - MODULE_LICENSE("GPL");
+2 -6
drivers/video/fbdev/core/fb_defio.c
··· 132 132 return 0; 133 133 134 134 inode_lock(inode); 135 - /* Kill off the delayed work */ 136 - cancel_delayed_work_sync(&info->deferred_work); 137 - 138 - /* Run it immediately */ 139 - schedule_delayed_work(&info->deferred_work, 0); 135 + flush_delayed_work(&info->deferred_work); 140 136 inode_unlock(inode); 141 137 142 138 return 0; ··· 315 319 struct page *page; 316 320 int i; 317 321 318 - cancel_delayed_work_sync(&info->deferred_work); 322 + flush_delayed_work(&info->deferred_work); 319 323 320 324 /* clear out the mapping that we setup */ 321 325 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
+1 -1
drivers/video/fbdev/fsl-diu-fb.c
··· 877 877 } 878 878 mutex_lock(&info->mm_lock); 879 879 info->screen_base = p; 880 - info->fix.smem_start = virt_to_phys(info->screen_base); 880 + info->fix.smem_start = virt_to_phys((__force const void *)info->screen_base); 881 881 info->fix.smem_len = smem_len; 882 882 mutex_unlock(&info->mm_lock); 883 883 info->screen_size = info->fix.smem_len;
+11 -2
drivers/video/fbdev/hgafb.c
··· 364 364 * hgafb_open - open the framebuffer device 365 365 * @info: pointer to fb_info object containing info for current hga board 366 366 * @init: open by console system or userland. 367 + * 368 + * Returns: %0 367 369 */ 368 370 369 371 static int hgafb_open(struct fb_info *info, int init) ··· 380 378 * hgafb_release - open the framebuffer device 381 379 * @info: pointer to fb_info object containing info for current hga board 382 380 * @init: open by console system or userland. 381 + * 382 + * Returns: %0 383 383 */ 384 384 385 385 static int hgafb_release(struct fb_info *info, int init) ··· 403 399 * This callback function is used to set the color registers of a HGA 404 400 * board. Since we have only two fixed colors only @regno is checked. 405 401 * A zero is returned on success and 1 for failure. 402 + * 403 + * Returns: %0 406 404 */ 407 405 408 406 static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ··· 416 410 } 417 411 418 412 /** 419 - * hga_pan_display - pan or wrap the display 413 + * hgafb_pan_display - pan or wrap the display 420 414 * @var:contains new xoffset, yoffset and vmode values 421 415 * @info:pointer to fb_info object containing info for current hga board 422 416 * 423 417 * This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP 424 418 * flag in @var. If input parameters are correct it calls hga_pan() to 425 419 * program the hardware. @info->var is updated to the new values. 426 - * A zero is returned on success and %-EINVAL for failure. 420 + * 421 + * Returns: %0 on success or %-EINVAL for failure. 427 422 */ 428 423 429 424 static int hgafb_pan_display(struct fb_var_screeninfo *var, ··· 456 449 * @blank_mode == 2 means suspend vsync, 457 450 * @blank_mode == 3 means suspend hsync, 458 451 * @blank_mode == 4 means powerdown. 452 + * 453 + * Returns: %0 459 454 */ 460 455 461 456 static int hgafb_blank(int blank_mode, struct fb_info *info)
+7 -13
drivers/video/fbdev/hyperv_fb.c
··· 48 48 #include <linux/aperture.h> 49 49 #include <linux/module.h> 50 50 #include <linux/kernel.h> 51 - #include <linux/screen_info.h> 52 51 #include <linux/vmalloc.h> 53 52 #include <linux/init.h> 54 53 #include <linux/completion.h> ··· 974 975 struct pci_dev *pdev = NULL; 975 976 void __iomem *fb_virt; 976 977 int gen2vm = efi_enabled(EFI_BOOT); 977 - resource_size_t base, size; 978 + resource_size_t base = 0; 979 + resource_size_t size = 0; 978 980 phys_addr_t paddr; 979 981 int ret; 980 982 ··· 1010 1010 goto getmem_done; 1011 1011 } 1012 1012 pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n"); 1013 - } else if (IS_ENABLED(CONFIG_SYSFB)) { 1014 - base = screen_info.lfb_base; 1015 - size = screen_info.lfb_size; 1016 1013 } else { 1017 1014 goto err1; 1018 1015 } ··· 1053 1056 info->screen_size = dio_fb_size; 1054 1057 1055 1058 getmem_done: 1056 - aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME); 1059 + if (base && size) 1060 + aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME); 1061 + else 1062 + aperture_remove_all_conflicting_devices(KBUILD_MODNAME); 1057 1063 1058 - if (!gen2vm) { 1064 + if (!gen2vm) 1059 1065 pci_dev_put(pdev); 1060 - } else if (IS_ENABLED(CONFIG_SYSFB)) { 1061 - /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */ 1062 - screen_info.lfb_size = 0; 1063 - screen_info.lfb_base = 0; 1064 - screen_info.orig_video_isVGA = 0; 1065 - } 1066 1066 1067 1067 return 0; 1068 1068
+102 -77
drivers/video/fbdev/imxfb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * Freescale i.MX Frame Buffer device driver 3 4 * 4 5 * Copyright (C) 2004 Sascha Hauer, Pengutronix 5 6 * Based on acornfb.c Copyright (C) Russell King. 6 - * 7 - * This file is subject to the terms and conditions of the GNU General Public 8 - * License. See the file COPYING in the main directory of this archive for 9 - * more details. 10 7 * 11 8 * Please direct your questions and comments on this driver to the following 12 9 * email address: ··· 31 34 #include <linux/math64.h> 32 35 #include <linux/of.h> 33 36 #include <linux/of_device.h> 37 + #include <linux/bitfield.h> 34 38 35 39 #include <linux/regulator/consumer.h> 36 40 37 41 #include <video/of_display_timing.h> 38 42 #include <video/of_videomode.h> 39 43 #include <video/videomode.h> 40 - 41 - #define PCR_TFT (1 << 31) 42 - #define PCR_BPIX_8 (3 << 25) 43 - #define PCR_BPIX_12 (4 << 25) 44 - #define PCR_BPIX_16 (5 << 25) 45 - #define PCR_BPIX_18 (6 << 25) 46 44 47 45 struct imx_fb_videomode { 48 46 struct fb_videomode mode; ··· 56 64 #define LCDC_SSA 0x00 57 65 58 66 #define LCDC_SIZE 0x04 59 - #define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20) 67 + #define SIZE_XMAX_MASK GENMASK(25, 20) 60 68 61 - #define YMAX_MASK_IMX1 0x1ff 62 - #define YMAX_MASK_IMX21 0x3ff 69 + #define YMAX_MASK_IMX1 GENMASK(8, 0) 70 + #define YMAX_MASK_IMX21 GENMASK(9, 0) 63 71 64 72 #define LCDC_VPW 0x08 65 - #define VPW_VPW(x) ((x) & 0x3ff) 73 + #define VPW_VPW_MASK GENMASK(9, 0) 66 74 67 75 #define LCDC_CPOS 0x0C 68 - #define CPOS_CC1 (1<<31) 69 - #define CPOS_CC0 (1<<30) 70 - #define CPOS_OP (1<<28) 71 - #define CPOS_CXP(x) (((x) & 3ff) << 16) 76 + #define CPOS_CC1 BIT(31) 77 + #define CPOS_CC0 BIT(30) 78 + #define CPOS_OP BIT(28) 79 + #define CPOS_CXP_MASK GENMASK(25, 16) 72 80 73 81 #define LCDC_LCWHB 0x10 74 - #define LCWHB_BK_EN (1<<31) 75 - #define LCWHB_CW(w) (((w) & 0x1f) << 24) 76 - #define LCWHB_CH(h) (((h) & 0x1f) << 16) 77 - #define LCWHB_BD(x) ((x) & 0xff) 82 + #define LCWHB_BK_EN BIT(31) 83 + #define LCWHB_CW_MASK GENMASK(28, 24) 84 + #define LCWHB_CH_MASK GENMASK(20, 16) 85 + #define LCWHB_BD_MASK GENMASK(7, 0) 78 86 79 87 #define LCDC_LCHCC 0x14 80 88 81 89 #define LCDC_PCR 0x18 90 + #define PCR_TFT BIT(31) 91 + #define PCR_COLOR BIT(30) 92 + #define PCR_BPIX_MASK GENMASK(27, 25) 93 + #define PCR_BPIX_8 3 94 + #define PCR_BPIX_12 4 95 + #define PCR_BPIX_16 5 96 + #define PCR_BPIX_18 6 97 + #define PCR_PCD_MASK GENMASK(5, 0) 82 98 83 99 #define LCDC_HCR 0x1C 84 - #define HCR_H_WIDTH(x) (((x) & 0x3f) << 26) 85 - #define HCR_H_WAIT_1(x) (((x) & 0xff) << 8) 86 - #define HCR_H_WAIT_2(x) ((x) & 0xff) 100 + #define HCR_H_WIDTH_MASK GENMASK(31, 26) 101 + #define HCR_H_WAIT_1_MASK GENMASK(15, 8) 102 + #define HCR_H_WAIT_2_MASK GENMASK(7, 0) 87 103 88 104 #define LCDC_VCR 0x20 89 - #define VCR_V_WIDTH(x) (((x) & 0x3f) << 26) 90 - #define VCR_V_WAIT_1(x) (((x) & 0xff) << 8) 91 - #define VCR_V_WAIT_2(x) ((x) & 0xff) 105 + #define VCR_V_WIDTH_MASK GENMASK(31, 26) 106 + #define VCR_V_WAIT_1_MASK GENMASK(15, 8) 107 + #define VCR_V_WAIT_2_MASK GENMASK(7, 0) 92 108 93 109 #define LCDC_POS 0x24 94 - #define POS_POS(x) ((x) & 1f) 110 + #define POS_POS_MASK GENMASK(4, 0) 95 111 96 112 #define LCDC_LSCR1 0x28 97 113 /* bit fields in imxfb.h */ ··· 112 112 113 113 #define LCDC_RMCR 0x34 114 114 115 - #define RMCR_LCDC_EN_MX1 (1<<1) 115 + #define RMCR_LCDC_EN_MX1 BIT(1) 116 116 117 - #define RMCR_SELF_REF (1<<0) 117 + #define RMCR_SELF_REF BIT(0) 118 118 119 119 #define LCDC_LCDICR 0x38 120 - #define LCDICR_INT_SYN (1<<2) 121 - #define LCDICR_INT_CON (1) 120 + #define LCDICR_INT_SYN BIT(2) 121 + #define LCDICR_INT_CON BIT(0) 122 122 123 123 #define LCDC_LCDISR 0x40 124 - #define LCDISR_UDR_ERR (1<<3) 125 - #define LCDISR_ERR_RES (1<<2) 126 - #define LCDISR_EOF (1<<1) 127 - #define LCDISR_BOF (1<<0) 124 + #define LCDISR_UDR_ERR BIT(3) 125 + #define LCDISR_ERR_RES BIT(2) 126 + #define LCDISR_EOF BIT(1) 127 + #define LCDISR_BOF BIT(0) 128 128 129 129 #define IMXFB_LSCR1_DEFAULT 0x00120300 130 130 131 131 #define LCDC_LAUSCR 0x80 132 - #define LAUSCR_AUS_MODE (1<<31) 132 + #define LAUSCR_AUS_MODE BIT(31) 133 133 134 134 /* Used fb-mode. Can be set on kernel command line, therefore file-static. */ 135 135 static const char *fb_mode; ··· 150 150 IMX21_FB, 151 151 }; 152 152 153 + enum imxfb_panel_type { 154 + PANEL_TYPE_MONOCHROME, 155 + PANEL_TYPE_CSTN, 156 + PANEL_TYPE_TFT, 157 + }; 158 + 153 159 struct imxfb_info { 154 160 struct platform_device *pdev; 155 161 void __iomem *regs; ··· 163 157 struct clk *clk_ahb; 164 158 struct clk *clk_per; 165 159 enum imxfb_type devtype; 160 + enum imxfb_panel_type panel_type; 166 161 bool enabled; 167 162 168 163 /* ··· 280 273 struct imxfb_info *fbi = info->par; 281 274 u_int val, ret = 1; 282 275 283 - #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 276 + #define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16) 284 277 if (regno < fbi->palette_size) { 285 278 val = (CNVT_TOHW(red, 4) << 8) | 286 - (CNVT_TOHW(green,4) << 4) | 279 + (CNVT_TOHW(green, 4) << 4) | 287 280 CNVT_TOHW(blue, 4); 288 281 289 282 writel(val, fbi->regs + 0x800 + (regno << 2)); ··· 412 405 413 406 pcr = (unsigned int)tmp; 414 407 415 - if (--pcr > 0x3F) { 416 - pcr = 0x3F; 417 - printk(KERN_WARNING "Must limit pixel clock to %luHz\n", 418 - lcd_clk / pcr); 408 + if (--pcr > PCR_PCD_MASK) { 409 + pcr = PCR_PCD_MASK; 410 + dev_warn(&fbi->pdev->dev, "Must limit pixel clock to %luHz\n", 411 + lcd_clk / pcr); 419 412 } 420 413 421 414 switch (var->bits_per_pixel) { 422 415 case 32: 423 - pcr |= PCR_BPIX_18; 416 + pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_18); 424 417 rgb = &def_rgb_18; 425 418 break; 426 419 case 16: 427 420 default: 428 421 if (is_imx1_fb(fbi)) 429 - pcr |= PCR_BPIX_12; 422 + pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_12); 430 423 else 431 - pcr |= PCR_BPIX_16; 424 + pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_16); 432 425 433 426 if (imxfb_mode->pcr & PCR_TFT) 434 427 rgb = &def_rgb_16_tft; ··· 436 429 rgb = &def_rgb_16_stn; 437 430 break; 438 431 case 8: 439 - pcr |= PCR_BPIX_8; 432 + pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_8); 440 433 rgb = &def_rgb_8; 441 434 break; 442 435 } 443 436 444 437 /* add sync polarities */ 445 - pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25)); 438 + pcr |= imxfb_mode->pcr & ~(PCR_PCD_MASK | PCR_BPIX_MASK); 446 439 447 440 fbi->pcr = pcr; 448 441 /* ··· 450 443 */ 451 444 if (!is_imx1_fb(fbi) && imxfb_mode->aus_mode) 452 445 fbi->lauscr = LAUSCR_AUS_MODE; 446 + 447 + if (imxfb_mode->pcr & PCR_TFT) 448 + fbi->panel_type = PANEL_TYPE_TFT; 449 + else if (imxfb_mode->pcr & PCR_COLOR) 450 + fbi->panel_type = PANEL_TYPE_CSTN; 451 + else 452 + fbi->panel_type = PANEL_TYPE_MONOCHROME; 453 453 454 454 /* 455 455 * Copy the RGB parameters for this display ··· 520 506 writel(fbi->map_dma, fbi->regs + LCDC_SSA); 521 507 522 508 /* panning offset 0 (0 pixel offset) */ 523 - writel(0x00000000, fbi->regs + LCDC_POS); 509 + writel(FIELD_PREP(POS_POS_MASK, 0), fbi->regs + LCDC_POS); 524 510 525 511 /* disable hardware cursor */ 526 512 writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1), ··· 576 562 { 577 563 struct imxfb_info *fbi = info->par; 578 564 579 - pr_debug("imxfb_blank: blank=%d\n", blank); 565 + pr_debug("%s: blank=%d\n", __func__, blank); 580 566 581 567 switch (blank) { 582 568 case FB_BLANK_POWERDOWN: ··· 610 596 { 611 597 struct imxfb_info *fbi = info->par; 612 598 u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21; 599 + u8 left_margin_low; 613 600 614 601 pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", 615 602 var->xres, var->hsync_len, ··· 619 604 var->yres, var->vsync_len, 620 605 var->upper_margin, var->lower_margin); 621 606 607 + if (fbi->panel_type == PANEL_TYPE_TFT) 608 + left_margin_low = 3; 609 + else if (fbi->panel_type == PANEL_TYPE_CSTN) 610 + left_margin_low = 2; 611 + else 612 + left_margin_low = 0; 613 + 622 614 #if DEBUG_VAR 623 615 if (var->xres < 16 || var->xres > 1024) 624 - printk(KERN_ERR "%s: invalid xres %d\n", 616 + dev_err(&fbi->pdev->dev, "%s: invalid xres %d\n", 625 617 info->fix.id, var->xres); 626 618 if (var->hsync_len < 1 || var->hsync_len > 64) 627 - printk(KERN_ERR "%s: invalid hsync_len %d\n", 619 + dev_err(&fbi->pdev->dev, "%s: invalid hsync_len %d\n", 628 620 info->fix.id, var->hsync_len); 629 - if (var->left_margin < 3 || var->left_margin > 255) 630 - printk(KERN_ERR "%s: invalid left_margin %d\n", 621 + if (var->left_margin < left_margin_low || var->left_margin > 255) 622 + dev_err(&fbi->pdev->dev, "%s: invalid left_margin %d\n", 631 623 info->fix.id, var->left_margin); 632 624 if (var->right_margin < 1 || var->right_margin > 255) 633 - printk(KERN_ERR "%s: invalid right_margin %d\n", 625 + dev_err(&fbi->pdev->dev, "%s: invalid right_margin %d\n", 634 626 info->fix.id, var->right_margin); 635 627 if (var->yres < 1 || var->yres > ymax_mask) 636 - printk(KERN_ERR "%s: invalid yres %d\n", 628 + dev_err(&fbi->pdev->dev, "%s: invalid yres %d\n", 637 629 info->fix.id, var->yres); 638 630 if (var->vsync_len > 100) 639 - printk(KERN_ERR "%s: invalid vsync_len %d\n", 631 + dev_err(&fbi->pdev->dev, "%s: invalid vsync_len %d\n", 640 632 info->fix.id, var->vsync_len); 641 633 if (var->upper_margin > 63) 642 - printk(KERN_ERR "%s: invalid upper_margin %d\n", 634 + dev_err(&fbi->pdev->dev, "%s: invalid upper_margin %d\n", 643 635 info->fix.id, var->upper_margin); 644 636 if (var->lower_margin > 255) 645 - printk(KERN_ERR "%s: invalid lower_margin %d\n", 637 + dev_err(&fbi->pdev->dev, "%s: invalid lower_margin %d\n", 646 638 info->fix.id, var->lower_margin); 647 639 #endif 648 640 649 641 /* physical screen start address */ 650 - writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4), 651 - fbi->regs + LCDC_VPW); 642 + writel(FIELD_PREP(VPW_VPW_MASK, 643 + var->xres * var->bits_per_pixel / 8 / 4), 644 + fbi->regs + LCDC_VPW); 652 645 653 - writel(HCR_H_WIDTH(var->hsync_len - 1) | 654 - HCR_H_WAIT_1(var->right_margin - 1) | 655 - HCR_H_WAIT_2(var->left_margin - 3), 656 - fbi->regs + LCDC_HCR); 646 + writel(FIELD_PREP(HCR_H_WIDTH_MASK, var->hsync_len - 1) | 647 + FIELD_PREP(HCR_H_WAIT_1_MASK, var->right_margin - 1) | 648 + FIELD_PREP(HCR_H_WAIT_2_MASK, 649 + var->left_margin - left_margin_low), 650 + fbi->regs + LCDC_HCR); 657 651 658 - writel(VCR_V_WIDTH(var->vsync_len) | 659 - VCR_V_WAIT_1(var->lower_margin) | 660 - VCR_V_WAIT_2(var->upper_margin), 661 - fbi->regs + LCDC_VCR); 652 + writel(FIELD_PREP(VCR_V_WIDTH_MASK, var->vsync_len) | 653 + FIELD_PREP(VCR_V_WAIT_1_MASK, var->lower_margin) | 654 + FIELD_PREP(VCR_V_WAIT_2_MASK, var->upper_margin), 655 + fbi->regs + LCDC_VCR); 662 656 663 - writel(SIZE_XMAX(var->xres) | (var->yres & ymax_mask), 664 - fbi->regs + LCDC_SIZE); 657 + writel(FIELD_PREP(SIZE_XMAX_MASK, var->xres >> 4) | 658 + (var->yres & ymax_mask), 659 + fbi->regs + LCDC_SIZE); 665 660 666 661 writel(fbi->pcr, fbi->regs + LCDC_PCR); 667 662 if (fbi->pwmr) ··· 694 669 struct imxfb_info *fbi = info->par; 695 670 struct device_node *np; 696 671 697 - pr_debug("%s\n",__func__); 698 - 699 672 info->pseudo_palette = devm_kmalloc_array(&pdev->dev, 16, 700 673 sizeof(u32), GFP_KERNEL); 701 674 if (!info->pseudo_palette) ··· 701 678 702 679 memset(fbi, 0, sizeof(struct imxfb_info)); 703 680 681 + fbi->pdev = pdev; 704 682 fbi->devtype = pdev->id_entry->driver_data; 705 683 706 684 strscpy(info->fix.id, IMX_NAME, sizeof(info->fix.id)); ··· 946 922 if (ret) 947 923 goto failed_init; 948 924 949 - /* Calculate maximum bytes used per pixel. In most cases this should 950 - * be the same as m->bpp/8 */ 925 + /* 926 + * Calculate maximum bytes used per pixel. In most cases this should 927 + * be the same as m->bpp/8 928 + */ 951 929 m = &fbi->mode[0]; 952 930 bytes_per_pixel = (m->bpp + 7) / 8; 953 931 for (i = 0; i < fbi->num_modes; i++, m++) ··· 1047 1021 lcd->props.max_contrast = 0xff; 1048 1022 1049 1023 imxfb_enable_controller(fbi); 1050 - fbi->pdev = pdev; 1051 1024 1052 1025 return 0; 1053 1026
-8
drivers/video/fbdev/intelfb/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_FB_INTEL) += intelfb.o 3 - 4 - intelfb-y := intelfbdrv.o intelfbhw.o 5 - intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o 6 - intelfb-objs := $(intelfb-y) 7 - 8 - ccflags-$(CONFIG_FB_INTEL_DEBUG) := -DDEBUG -DREGDUMP
-382
drivers/video/fbdev/intelfb/intelfb.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _INTELFB_H 3 - #define _INTELFB_H 4 - 5 - /* $DHD: intelfb/intelfb.h,v 1.40 2003/06/27 15:06:25 dawes Exp $ */ 6 - 7 - #include <linux/agp_backend.h> 8 - #include <linux/fb.h> 9 - 10 - #ifdef CONFIG_FB_INTEL_I2C 11 - #include <linux/i2c.h> 12 - #include <linux/i2c-algo-bit.h> 13 - #endif 14 - 15 - /*** Version/name ***/ 16 - #define INTELFB_VERSION "0.9.6" 17 - #define INTELFB_MODULE_NAME "intelfb" 18 - #define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM" 19 - 20 - 21 - /*** Debug/feature defines ***/ 22 - 23 - #ifndef DEBUG 24 - #define DEBUG 0 25 - #endif 26 - 27 - #ifndef VERBOSE 28 - #define VERBOSE 0 29 - #endif 30 - 31 - #ifndef REGDUMP 32 - #define REGDUMP 0 33 - #endif 34 - 35 - #ifndef DETECT_VGA_CLASS_ONLY 36 - #define DETECT_VGA_CLASS_ONLY 1 37 - #endif 38 - 39 - #ifndef ALLOCATE_FOR_PANNING 40 - #define ALLOCATE_FOR_PANNING 1 41 - #endif 42 - 43 - #ifndef PREFERRED_MODE 44 - #define PREFERRED_MODE "1024x768-32@70" 45 - #endif 46 - 47 - /*** hw-related values ***/ 48 - 49 - /* Resource Allocation */ 50 - #define INTELFB_FB_ACQUIRED 1 51 - #define INTELFB_MMIO_ACQUIRED 2 52 - 53 - /* PCI ids for supported devices */ 54 - #define PCI_DEVICE_ID_INTEL_830M 0x3577 55 - #define PCI_DEVICE_ID_INTEL_845G 0x2562 56 - #define PCI_DEVICE_ID_INTEL_85XGM 0x3582 57 - #define PCI_DEVICE_ID_INTEL_854 0x358E 58 - #define PCI_DEVICE_ID_INTEL_865G 0x2572 59 - #define PCI_DEVICE_ID_INTEL_915G 0x2582 60 - #define PCI_DEVICE_ID_INTEL_915GM 0x2592 61 - #define PCI_DEVICE_ID_INTEL_945G 0x2772 62 - #define PCI_DEVICE_ID_INTEL_945GM 0x27A2 63 - #define PCI_DEVICE_ID_INTEL_945GME 0x27AE 64 - #define PCI_DEVICE_ID_INTEL_965G 0x29A2 65 - #define PCI_DEVICE_ID_INTEL_965GM 0x2A02 66 - 67 - /* Size of MMIO region */ 68 - #define INTEL_REG_SIZE 0x80000 69 - 70 - #define STRIDE_ALIGNMENT 16 71 - #define STRIDE_ALIGNMENT_I9XX 64 72 - 73 - #define PALETTE_8_ENTRIES 256 74 - 75 - 76 - /*** Macros ***/ 77 - 78 - /* basic arithmetic */ 79 - #define KB(x) ((x) * 1024) 80 - #define MB(x) ((x) * 1024 * 1024) 81 - #define BtoKB(x) ((x) / 1024) 82 - #define BtoMB(x) ((x) / 1024 / 1024) 83 - 84 - #define GTT_PAGE_SIZE KB(4) 85 - 86 - #define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y)) 87 - #define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) 88 - #define ROUND_UP_TO_PAGE(x) ROUND_UP_TO((x), GTT_PAGE_SIZE) 89 - #define ROUND_DOWN_TO_PAGE(x) ROUND_DOWN_TO((x), GTT_PAGE_SIZE) 90 - 91 - /* messages */ 92 - #define PFX INTELFB_MODULE_NAME ": " 93 - 94 - #define ERR_MSG(fmt, args...) printk(KERN_ERR PFX fmt, ## args) 95 - #define WRN_MSG(fmt, args...) printk(KERN_WARNING PFX fmt, ## args) 96 - #define NOT_MSG(fmt, args...) printk(KERN_NOTICE PFX fmt, ## args) 97 - #define INF_MSG(fmt, args...) printk(KERN_INFO PFX fmt, ## args) 98 - #if DEBUG 99 - #define DBG_MSG(fmt, args...) printk(KERN_DEBUG PFX fmt, ## args) 100 - #else 101 - #define DBG_MSG(fmt, args...) while (0) printk(fmt, ## args) 102 - #endif 103 - 104 - /* get commonly used pointers */ 105 - #define GET_DINFO(info) (info)->par 106 - 107 - /* misc macros */ 108 - #define ACCEL(d, i) \ 109 - ((d)->accel && !(d)->ring_lockup && \ 110 - ((i)->var.accel_flags & FB_ACCELF_TEXT)) 111 - 112 - /*#define NOACCEL_CHIPSET(d) \ 113 - ((d)->chipset != INTEL_865G)*/ 114 - #define NOACCEL_CHIPSET(d) \ 115 - (0) 116 - 117 - #define FIXED_MODE(d) ((d)->fixed_mode) 118 - 119 - /*** Driver parameters ***/ 120 - 121 - #define RINGBUFFER_SIZE KB(64) 122 - #define HW_CURSOR_SIZE KB(4) 123 - 124 - /* Intel agpgart driver */ 125 - #define AGP_PHYSICAL_MEMORY 2 126 - 127 - /* store information about an Ixxx DVO */ 128 - /* The i830->i865 use multiple DVOs with multiple i2cs */ 129 - /* the i915, i945 have a single sDVO i2c bus - which is different */ 130 - #define MAX_OUTPUTS 6 131 - 132 - /* these are outputs from the chip - integrated only 133 - external chips are via DVO or SDVO output */ 134 - #define INTELFB_OUTPUT_UNUSED 0 135 - #define INTELFB_OUTPUT_ANALOG 1 136 - #define INTELFB_OUTPUT_DVO 2 137 - #define INTELFB_OUTPUT_SDVO 3 138 - #define INTELFB_OUTPUT_LVDS 4 139 - #define INTELFB_OUTPUT_TVOUT 5 140 - 141 - #define INTELFB_DVO_CHIP_NONE 0 142 - #define INTELFB_DVO_CHIP_LVDS 1 143 - #define INTELFB_DVO_CHIP_TMDS 2 144 - #define INTELFB_DVO_CHIP_TVOUT 4 145 - 146 - #define INTELFB_OUTPUT_PIPE_NC 0 147 - #define INTELFB_OUTPUT_PIPE_A 1 148 - #define INTELFB_OUTPUT_PIPE_B 2 149 - 150 - /*** Data Types ***/ 151 - 152 - /* supported chipsets */ 153 - enum intel_chips { 154 - INTEL_830M, 155 - INTEL_845G, 156 - INTEL_85XGM, 157 - INTEL_852GM, 158 - INTEL_852GME, 159 - INTEL_854, 160 - INTEL_855GM, 161 - INTEL_855GME, 162 - INTEL_865G, 163 - INTEL_915G, 164 - INTEL_915GM, 165 - INTEL_945G, 166 - INTEL_945GM, 167 - INTEL_945GME, 168 - INTEL_965G, 169 - INTEL_965GM, 170 - }; 171 - 172 - struct intelfb_hwstate { 173 - u32 vga0_divisor; 174 - u32 vga1_divisor; 175 - u32 vga_pd; 176 - u32 dpll_a; 177 - u32 dpll_b; 178 - u32 fpa0; 179 - u32 fpa1; 180 - u32 fpb0; 181 - u32 fpb1; 182 - u32 palette_a[PALETTE_8_ENTRIES]; 183 - u32 palette_b[PALETTE_8_ENTRIES]; 184 - u32 htotal_a; 185 - u32 hblank_a; 186 - u32 hsync_a; 187 - u32 vtotal_a; 188 - u32 vblank_a; 189 - u32 vsync_a; 190 - u32 src_size_a; 191 - u32 bclrpat_a; 192 - u32 htotal_b; 193 - u32 hblank_b; 194 - u32 hsync_b; 195 - u32 vtotal_b; 196 - u32 vblank_b; 197 - u32 vsync_b; 198 - u32 src_size_b; 199 - u32 bclrpat_b; 200 - u32 adpa; 201 - u32 dvoa; 202 - u32 dvob; 203 - u32 dvoc; 204 - u32 dvoa_srcdim; 205 - u32 dvob_srcdim; 206 - u32 dvoc_srcdim; 207 - u32 lvds; 208 - u32 pipe_a_conf; 209 - u32 pipe_b_conf; 210 - u32 disp_arb; 211 - u32 cursor_a_control; 212 - u32 cursor_b_control; 213 - u32 cursor_a_base; 214 - u32 cursor_b_base; 215 - u32 cursor_size; 216 - u32 disp_a_ctrl; 217 - u32 disp_b_ctrl; 218 - u32 disp_a_base; 219 - u32 disp_b_base; 220 - u32 cursor_a_palette[4]; 221 - u32 cursor_b_palette[4]; 222 - u32 disp_a_stride; 223 - u32 disp_b_stride; 224 - u32 vgacntrl; 225 - u32 add_id; 226 - u32 swf0x[7]; 227 - u32 swf1x[7]; 228 - u32 swf3x[3]; 229 - u32 fence[8]; 230 - u32 instpm; 231 - u32 mem_mode; 232 - u32 fw_blc_0; 233 - u32 fw_blc_1; 234 - u16 hwstam; 235 - u16 ier; 236 - u16 iir; 237 - u16 imr; 238 - }; 239 - 240 - struct intelfb_heap_data { 241 - u32 physical; 242 - u8 __iomem *virtual; 243 - u32 offset; /* in GATT pages */ 244 - u32 size; /* in bytes */ 245 - }; 246 - 247 - #ifdef CONFIG_FB_INTEL_I2C 248 - struct intelfb_i2c_chan { 249 - struct intelfb_info *dinfo; 250 - u32 reg; 251 - struct i2c_adapter adapter; 252 - struct i2c_algo_bit_data algo; 253 - }; 254 - #endif 255 - 256 - struct intelfb_output_rec { 257 - int type; 258 - int pipe; 259 - int flags; 260 - 261 - #ifdef CONFIG_FB_INTEL_I2C 262 - struct intelfb_i2c_chan i2c_bus; 263 - struct intelfb_i2c_chan ddc_bus; 264 - #endif 265 - }; 266 - 267 - struct intelfb_vsync { 268 - wait_queue_head_t wait; 269 - unsigned int count; 270 - int pan_display; 271 - u32 pan_offset; 272 - }; 273 - 274 - struct intelfb_info { 275 - struct fb_info *info; 276 - const struct fb_ops *fbops; 277 - struct pci_dev *pdev; 278 - 279 - struct intelfb_hwstate save_state; 280 - 281 - /* agpgart structs */ 282 - struct agp_memory *gtt_fb_mem; /* use all stolen memory or vram */ 283 - struct agp_memory *gtt_ring_mem; /* ring buffer */ 284 - struct agp_memory *gtt_cursor_mem; /* hw cursor */ 285 - 286 - /* use a gart reserved fb mem */ 287 - u8 fbmem_gart; 288 - 289 - int wc_cookie; 290 - 291 - /* heap data */ 292 - struct intelfb_heap_data aperture; 293 - struct intelfb_heap_data fb; 294 - struct intelfb_heap_data ring; 295 - struct intelfb_heap_data cursor; 296 - 297 - /* mmio regs */ 298 - u32 mmio_base_phys; 299 - u8 __iomem *mmio_base; 300 - 301 - /* fb start offset (in bytes) */ 302 - u32 fb_start; 303 - 304 - /* ring buffer */ 305 - u32 ring_head; 306 - u32 ring_tail; 307 - u32 ring_tail_mask; 308 - u32 ring_space; 309 - u32 ring_lockup; 310 - 311 - /* palette */ 312 - u32 pseudo_palette[16]; 313 - 314 - /* chip info */ 315 - int pci_chipset; 316 - int chipset; 317 - const char *name; 318 - int mobile; 319 - 320 - /* current mode */ 321 - int bpp, depth; 322 - u32 visual; 323 - int xres, yres, pitch; 324 - int pixclock; 325 - 326 - /* current pipe */ 327 - int pipe; 328 - 329 - /* some flags */ 330 - int accel; 331 - int hwcursor; 332 - int fixed_mode; 333 - int ring_active; 334 - int flag; 335 - unsigned long irq_flags; 336 - int open; 337 - 338 - /* vsync */ 339 - struct intelfb_vsync vsync; 340 - spinlock_t int_lock; 341 - 342 - /* hw cursor */ 343 - int cursor_on; 344 - int cursor_blanked; 345 - u8 cursor_src[64]; 346 - 347 - /* initial parameters */ 348 - int initial_vga; 349 - struct fb_var_screeninfo initial_var; 350 - u32 initial_fb_base; 351 - u32 initial_video_ram; 352 - u32 initial_pitch; 353 - 354 - /* driver registered */ 355 - int registered; 356 - 357 - /* index into plls */ 358 - int pll_index; 359 - 360 - /* outputs */ 361 - int num_outputs; 362 - struct intelfb_output_rec output[MAX_OUTPUTS]; 363 - }; 364 - 365 - #define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G) || \ 366 - ((dinfo)->chipset == INTEL_915GM) || \ 367 - ((dinfo)->chipset == INTEL_945G) || \ 368 - ((dinfo)->chipset == INTEL_945GM) || \ 369 - ((dinfo)->chipset == INTEL_945GME) || \ 370 - ((dinfo)->chipset == INTEL_965G) || \ 371 - ((dinfo)->chipset == INTEL_965GM)) 372 - 373 - /*** function prototypes ***/ 374 - 375 - extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); 376 - 377 - #ifdef CONFIG_FB_INTEL_I2C 378 - extern void intelfb_create_i2c_busses(struct intelfb_info *dinfo); 379 - extern void intelfb_delete_i2c_busses(struct intelfb_info *dinfo); 380 - #endif 381 - 382 - #endif /* _INTELFB_H */
-209
drivers/video/fbdev/intelfb/intelfb_i2c.c
··· 1 - /************************************************************************** 2 - 3 - Copyright 2006 Dave Airlie <airlied@linux.ie> 4 - 5 - All Rights Reserved. 6 - 7 - Permission is hereby granted, free of charge, to any person obtaining a 8 - copy of this software and associated documentation files (the "Software"), 9 - to deal in the Software without restriction, including without limitation 10 - on the rights to use, copy, modify, merge, publish, distribute, sub 11 - license, and/or sell copies of the Software, and to permit persons to whom 12 - the Software is furnished to do so, subject to the following conditions: 13 - 14 - The above copyright notice and this permission notice (including the next 15 - paragraph) shall be included in all copies or substantial portions of the 16 - Software. 17 - 18 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 - THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 22 - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23 - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24 - USE OR OTHER DEALINGS IN THE SOFTWARE. 25 - 26 - **************************************************************************/ 27 - 28 - #include <linux/module.h> 29 - #include <linux/kernel.h> 30 - #include <linux/delay.h> 31 - #include <linux/pci.h> 32 - #include <linux/fb.h> 33 - 34 - #include <linux/i2c.h> 35 - #include <linux/i2c-algo-bit.h> 36 - 37 - #include <asm/io.h> 38 - 39 - #include "intelfb.h" 40 - #include "intelfbhw.h" 41 - 42 - /* bit locations in the registers */ 43 - #define SCL_DIR_MASK 0x0001 44 - #define SCL_DIR 0x0002 45 - #define SCL_VAL_MASK 0x0004 46 - #define SCL_VAL_OUT 0x0008 47 - #define SCL_VAL_IN 0x0010 48 - #define SDA_DIR_MASK 0x0100 49 - #define SDA_DIR 0x0200 50 - #define SDA_VAL_MASK 0x0400 51 - #define SDA_VAL_OUT 0x0800 52 - #define SDA_VAL_IN 0x1000 53 - 54 - static void intelfb_gpio_setscl(void *data, int state) 55 - { 56 - struct intelfb_i2c_chan *chan = data; 57 - struct intelfb_info *dinfo = chan->dinfo; 58 - u32 val; 59 - 60 - OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | 61 - SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); 62 - val = INREG(chan->reg); 63 - } 64 - 65 - static void intelfb_gpio_setsda(void *data, int state) 66 - { 67 - struct intelfb_i2c_chan *chan = data; 68 - struct intelfb_info *dinfo = chan->dinfo; 69 - u32 val; 70 - 71 - OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | 72 - SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); 73 - val = INREG(chan->reg); 74 - } 75 - 76 - static int intelfb_gpio_getscl(void *data) 77 - { 78 - struct intelfb_i2c_chan *chan = data; 79 - struct intelfb_info *dinfo = chan->dinfo; 80 - u32 val; 81 - 82 - OUTREG(chan->reg, SCL_DIR_MASK); 83 - OUTREG(chan->reg, 0); 84 - val = INREG(chan->reg); 85 - return ((val & SCL_VAL_IN) != 0); 86 - } 87 - 88 - static int intelfb_gpio_getsda(void *data) 89 - { 90 - struct intelfb_i2c_chan *chan = data; 91 - struct intelfb_info *dinfo = chan->dinfo; 92 - u32 val; 93 - 94 - OUTREG(chan->reg, SDA_DIR_MASK); 95 - OUTREG(chan->reg, 0); 96 - val = INREG(chan->reg); 97 - return ((val & SDA_VAL_IN) != 0); 98 - } 99 - 100 - static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, 101 - struct intelfb_i2c_chan *chan, 102 - const u32 reg, const char *name, 103 - int class) 104 - { 105 - int rc; 106 - 107 - chan->dinfo = dinfo; 108 - chan->reg = reg; 109 - snprintf(chan->adapter.name, sizeof(chan->adapter.name), 110 - "intelfb %s", name); 111 - chan->adapter.class = class; 112 - chan->adapter.owner = THIS_MODULE; 113 - chan->adapter.algo_data = &chan->algo; 114 - chan->adapter.dev.parent = &chan->dinfo->pdev->dev; 115 - chan->algo.setsda = intelfb_gpio_setsda; 116 - chan->algo.setscl = intelfb_gpio_setscl; 117 - chan->algo.getsda = intelfb_gpio_getsda; 118 - chan->algo.getscl = intelfb_gpio_getscl; 119 - chan->algo.udelay = 40; 120 - chan->algo.timeout = 20; 121 - chan->algo.data = chan; 122 - 123 - i2c_set_adapdata(&chan->adapter, chan); 124 - 125 - /* Raise SCL and SDA */ 126 - intelfb_gpio_setsda(chan, 1); 127 - intelfb_gpio_setscl(chan, 1); 128 - udelay(20); 129 - 130 - rc = i2c_bit_add_bus(&chan->adapter); 131 - if (rc == 0) 132 - DBG_MSG("I2C bus %s registered.\n", name); 133 - else 134 - WRN_MSG("Failed to register I2C bus %s.\n", name); 135 - return rc; 136 - } 137 - 138 - void intelfb_create_i2c_busses(struct intelfb_info *dinfo) 139 - { 140 - int i = 0; 141 - 142 - /* everyone has at least a single analog output */ 143 - dinfo->num_outputs = 1; 144 - dinfo->output[i].type = INTELFB_OUTPUT_ANALOG; 145 - 146 - /* setup the DDC bus for analog output */ 147 - intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, 148 - "CRTDDC_A", I2C_CLASS_DDC); 149 - i++; 150 - 151 - /* need to add the output busses for each device 152 - - this function is very incomplete 153 - - i915GM has LVDS and TVOUT for example 154 - */ 155 - switch(dinfo->chipset) { 156 - case INTEL_830M: 157 - case INTEL_845G: 158 - case INTEL_854: 159 - case INTEL_855GM: 160 - case INTEL_865G: 161 - dinfo->output[i].type = INTELFB_OUTPUT_DVO; 162 - intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, 163 - GPIOD, "DVODDC_D", I2C_CLASS_DDC); 164 - intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, 165 - GPIOE, "DVOI2C_E", 0); 166 - i++; 167 - break; 168 - case INTEL_915G: 169 - case INTEL_915GM: 170 - /* has some LVDS + tv-out */ 171 - case INTEL_945G: 172 - case INTEL_945GM: 173 - case INTEL_945GME: 174 - case INTEL_965G: 175 - case INTEL_965GM: 176 - /* SDVO ports have a single control bus - 2 devices */ 177 - dinfo->output[i].type = INTELFB_OUTPUT_SDVO; 178 - intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, 179 - GPIOE, "SDVOCTRL_E", 0); 180 - /* TODO: initialize the SDVO */ 181 - /* I830SDVOInit(pScrn, i, DVOB); */ 182 - i++; 183 - 184 - /* set up SDVOC */ 185 - dinfo->output[i].type = INTELFB_OUTPUT_SDVO; 186 - dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus; 187 - /* TODO: initialize the SDVO */ 188 - /* I830SDVOInit(pScrn, i, DVOC); */ 189 - i++; 190 - break; 191 - } 192 - dinfo->num_outputs = i; 193 - } 194 - 195 - void intelfb_delete_i2c_busses(struct intelfb_info *dinfo) 196 - { 197 - int i; 198 - 199 - for (i = 0; i < MAX_OUTPUTS; i++) { 200 - if (dinfo->output[i].i2c_bus.dinfo) { 201 - i2c_del_adapter(&dinfo->output[i].i2c_bus.adapter); 202 - dinfo->output[i].i2c_bus.dinfo = NULL; 203 - } 204 - if (dinfo->output[i].ddc_bus.dinfo) { 205 - i2c_del_adapter(&dinfo->output[i].ddc_bus.adapter); 206 - dinfo->output[i].ddc_bus.dinfo = NULL; 207 - } 208 - } 209 - }
-1680
drivers/video/fbdev/intelfb/intelfbdrv.c
··· 1 - /* 2 - * intelfb 3 - * 4 - * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/ 5 - * 945G/945GM/945GME/965G/965GM integrated graphics chips. 6 - * 7 - * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> 8 - * 2004 Sylvain Meyer 9 - * 2006 David Airlie 10 - * 11 - * This driver consists of two parts. The first part (intelfbdrv.c) provides 12 - * the basic fbdev interfaces, is derived in part from the radeonfb and 13 - * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c) 14 - * provides the code to program the hardware. Most of it is derived from 15 - * the i810/i830 XFree86 driver. The HW-specific code is covered here 16 - * under a dual license (GPL and MIT/XFree86 license). 17 - * 18 - * Author: David Dawes 19 - * 20 - */ 21 - 22 - /* $DHD: intelfb/intelfbdrv.c,v 1.20 2003/06/27 15:17:40 dawes Exp $ */ 23 - 24 - /* 25 - * Changes: 26 - * 01/2003 - Initial driver (0.1.0), no mode switching, no acceleration. 27 - * This initial version is a basic core that works a lot like 28 - * the vesafb driver. It must be built-in to the kernel, 29 - * and the initial video mode must be set with vga=XXX at 30 - * boot time. (David Dawes) 31 - * 32 - * 01/2003 - Version 0.2.0: Mode switching added, colormap support 33 - * implemented, Y panning, and soft screen blanking implemented. 34 - * No acceleration yet. (David Dawes) 35 - * 36 - * 01/2003 - Version 0.3.0: fbcon acceleration support added. Module 37 - * option handling added. (David Dawes) 38 - * 39 - * 01/2003 - Version 0.4.0: fbcon HW cursor support added. (David Dawes) 40 - * 41 - * 01/2003 - Version 0.4.1: Add auto-generation of built-in modes. 42 - * (David Dawes) 43 - * 44 - * 02/2003 - Version 0.4.2: Add check for active non-CRT devices, and 45 - * mode validation checks. (David Dawes) 46 - * 47 - * 02/2003 - Version 0.4.3: Check when the VC is in graphics mode so that 48 - * acceleration is disabled while an XFree86 server is running. 49 - * (David Dawes) 50 - * 51 - * 02/2003 - Version 0.4.4: Monitor DPMS support. (David Dawes) 52 - * 53 - * 02/2003 - Version 0.4.5: Basic XFree86 + fbdev working. (David Dawes) 54 - * 55 - * 02/2003 - Version 0.5.0: Modify to work with the 2.5.32 kernel as well 56 - * as 2.4.x kernels. (David Dawes) 57 - * 58 - * 02/2003 - Version 0.6.0: Split out HW-specifics into a separate file. 59 - * (David Dawes) 60 - * 61 - * 02/2003 - Version 0.7.0: Test on 852GM/855GM. Acceleration and HW 62 - * cursor are disabled on this platform. (David Dawes) 63 - * 64 - * 02/2003 - Version 0.7.1: Test on 845G. Acceleration is disabled 65 - * on this platform. (David Dawes) 66 - * 67 - * 02/2003 - Version 0.7.2: Test on 830M. Acceleration and HW 68 - * cursor are disabled on this platform. (David Dawes) 69 - * 70 - * 02/2003 - Version 0.7.3: Fix 8-bit modes for mobile platforms 71 - * (David Dawes) 72 - * 73 - * 02/2003 - Version 0.7.4: Add checks for FB and FBCON_HAS_CFB* configured 74 - * in the kernel, and add mode bpp verification and default 75 - * bpp selection based on which FBCON_HAS_CFB* are configured. 76 - * (David Dawes) 77 - * 78 - * 02/2003 - Version 0.7.5: Add basic package/install scripts based on the 79 - * DRI packaging scripts. (David Dawes) 80 - * 81 - * 04/2003 - Version 0.7.6: Fix typo that affects builds with SMP-enabled 82 - * kernels. (David Dawes, reported by Anupam). 83 - * 84 - * 06/2003 - Version 0.7.7: 85 - * Fix Makefile.kernel build problem (Tsutomu Yasuda). 86 - * Fix mis-placed #endif (2.4.21 kernel). 87 - * 88 - * 09/2004 - Version 0.9.0 - by Sylvain Meyer 89 - * Port to linux 2.6 kernel fbdev 90 - * Fix HW accel and HW cursor on i845G 91 - * Use of agpgart for fb memory reservation 92 - * Add mtrr support 93 - * 94 - * 10/2004 - Version 0.9.1 95 - * Use module_param instead of old MODULE_PARM 96 - * Some cleanup 97 - * 98 - * 11/2004 - Version 0.9.2 99 - * Add vram option to reserve more memory than stolen by BIOS 100 - * Fix intelfbhw_pan_display typo 101 - * Add __initdata annotations 102 - * 103 - * 04/2008 - Version 0.9.5 104 - * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>) 105 - * 106 - * 08/2008 - Version 0.9.6 107 - * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>) 108 - */ 109 - 110 - #include <linux/aperture.h> 111 - #include <linux/module.h> 112 - #include <linux/kernel.h> 113 - #include <linux/errno.h> 114 - #include <linux/string.h> 115 - #include <linux/mm.h> 116 - #include <linux/slab.h> 117 - #include <linux/delay.h> 118 - #include <linux/fb.h> 119 - #include <linux/ioport.h> 120 - #include <linux/init.h> 121 - #include <linux/pci.h> 122 - #include <linux/vmalloc.h> 123 - #include <linux/pagemap.h> 124 - #include <linux/screen_info.h> 125 - 126 - #include <asm/io.h> 127 - 128 - #include "intelfb.h" 129 - #include "intelfbhw.h" 130 - #include "../edid.h" 131 - 132 - static void get_initial_mode(struct intelfb_info *dinfo); 133 - static void update_dinfo(struct intelfb_info *dinfo, 134 - struct fb_var_screeninfo *var); 135 - static int intelfb_open(struct fb_info *info, int user); 136 - static int intelfb_release(struct fb_info *info, int user); 137 - static int intelfb_check_var(struct fb_var_screeninfo *var, 138 - struct fb_info *info); 139 - static int intelfb_set_par(struct fb_info *info); 140 - static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 141 - unsigned blue, unsigned transp, 142 - struct fb_info *info); 143 - 144 - static int intelfb_blank(int blank, struct fb_info *info); 145 - static int intelfb_pan_display(struct fb_var_screeninfo *var, 146 - struct fb_info *info); 147 - 148 - static void intelfb_fillrect(struct fb_info *info, 149 - const struct fb_fillrect *rect); 150 - static void intelfb_copyarea(struct fb_info *info, 151 - const struct fb_copyarea *region); 152 - static void intelfb_imageblit(struct fb_info *info, 153 - const struct fb_image *image); 154 - static int intelfb_cursor(struct fb_info *info, 155 - struct fb_cursor *cursor); 156 - 157 - static int intelfb_sync(struct fb_info *info); 158 - 159 - static int intelfb_ioctl(struct fb_info *info, 160 - unsigned int cmd, unsigned long arg); 161 - 162 - static int intelfb_pci_register(struct pci_dev *pdev, 163 - const struct pci_device_id *ent); 164 - static void intelfb_pci_unregister(struct pci_dev *pdev); 165 - static int intelfb_set_fbinfo(struct intelfb_info *dinfo); 166 - 167 - /* 168 - * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the 169 - * mobile chipsets from being registered. 170 - */ 171 - #if DETECT_VGA_CLASS_ONLY 172 - #define INTELFB_CLASS_MASK ~0 << 8 173 - #else 174 - #define INTELFB_CLASS_MASK 0 175 - #endif 176 - 177 - static const struct pci_device_id intelfb_pci_table[] = { 178 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830M, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_830M }, 179 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G }, 180 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, 181 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, 182 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_854, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_854 }, 183 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, 184 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, 185 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, 186 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM }, 187 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME }, 188 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G }, 189 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM }, 190 - { 0, } 191 - }; 192 - 193 - /* Global data */ 194 - static int num_registered = 0; 195 - 196 - /* fb ops */ 197 - static const struct fb_ops intel_fb_ops = { 198 - .owner = THIS_MODULE, 199 - .fb_open = intelfb_open, 200 - .fb_release = intelfb_release, 201 - __FB_DEFAULT_IOMEM_OPS_RDWR, 202 - .fb_check_var = intelfb_check_var, 203 - .fb_set_par = intelfb_set_par, 204 - .fb_setcolreg = intelfb_setcolreg, 205 - .fb_blank = intelfb_blank, 206 - .fb_pan_display = intelfb_pan_display, 207 - .fb_fillrect = intelfb_fillrect, 208 - .fb_copyarea = intelfb_copyarea, 209 - .fb_imageblit = intelfb_imageblit, 210 - .fb_cursor = intelfb_cursor, 211 - .fb_sync = intelfb_sync, 212 - .fb_ioctl = intelfb_ioctl, 213 - __FB_DEFAULT_IOMEM_OPS_MMAP, 214 - }; 215 - 216 - /* PCI driver module table */ 217 - static struct pci_driver intelfb_driver = { 218 - .name = "intelfb", 219 - .id_table = intelfb_pci_table, 220 - .probe = intelfb_pci_register, 221 - .remove = intelfb_pci_unregister, 222 - }; 223 - 224 - /* Module description/parameters */ 225 - MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, " 226 - "Sylvain Meyer <sylvain.meyer@worldonline.fr>"); 227 - MODULE_DESCRIPTION("Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS 228 - " chipsets"); 229 - MODULE_LICENSE("Dual BSD/GPL"); 230 - MODULE_DEVICE_TABLE(pci, intelfb_pci_table); 231 - 232 - static bool accel = 1; 233 - static int vram = 4; 234 - static bool hwcursor = 0; 235 - static bool mtrr = 1; 236 - static bool fixed = 0; 237 - static bool noinit = 0; 238 - static bool noregister = 0; 239 - static bool probeonly = 0; 240 - static bool idonly = 0; 241 - static int bailearly = 0; 242 - static int voffset = 48; 243 - static char *mode = NULL; 244 - 245 - module_param(accel, bool, S_IRUGO); 246 - MODULE_PARM_DESC(accel, "Enable hardware acceleration"); 247 - module_param(vram, int, S_IRUGO); 248 - MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB"); 249 - module_param(voffset, int, S_IRUGO); 250 - MODULE_PARM_DESC(voffset, "Offset of framebuffer in MiB"); 251 - module_param(hwcursor, bool, S_IRUGO); 252 - MODULE_PARM_DESC(hwcursor, "Enable HW cursor"); 253 - module_param(mtrr, bool, S_IRUGO); 254 - MODULE_PARM_DESC(mtrr, "Enable MTRR support"); 255 - module_param(fixed, bool, S_IRUGO); 256 - MODULE_PARM_DESC(fixed, "Disable mode switching"); 257 - module_param(noinit, bool, 0); 258 - MODULE_PARM_DESC(noinit, "Don't initialise graphics mode when loading"); 259 - module_param(noregister, bool, 0); 260 - MODULE_PARM_DESC(noregister, "Don't register, just probe and exit (debug)"); 261 - module_param(probeonly, bool, 0); 262 - MODULE_PARM_DESC(probeonly, "Do a minimal probe (debug)"); 263 - module_param(idonly, bool, 0); 264 - MODULE_PARM_DESC(idonly, "Just identify without doing anything else (debug)"); 265 - module_param(bailearly, int, 0); 266 - MODULE_PARM_DESC(bailearly, "Bail out early, depending on value (debug)"); 267 - module_param(mode, charp, S_IRUGO); 268 - MODULE_PARM_DESC(mode, 269 - "Initial video mode \"<xres>x<yres>[-<depth>][@<refresh>]\""); 270 - 271 - #ifndef MODULE 272 - #define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name))) 273 - #define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0) 274 - #define OPT_STRVAL(opt, name) (opt + strlen(name)) 275 - 276 - static __inline__ char * get_opt_string(const char *this_opt, const char *name) 277 - { 278 - const char *p; 279 - int i; 280 - char *ret; 281 - 282 - p = OPT_STRVAL(this_opt, name); 283 - i = 0; 284 - while (p[i] && p[i] != ' ' && p[i] != ',') 285 - i++; 286 - ret = kmalloc(i + 1, GFP_KERNEL); 287 - if (ret) { 288 - strncpy(ret, p, i); 289 - ret[i] = '\0'; 290 - } 291 - return ret; 292 - } 293 - 294 - static __inline__ int get_opt_int(const char *this_opt, const char *name, 295 - int *ret) 296 - { 297 - if (!ret) 298 - return 0; 299 - 300 - if (!OPT_EQUAL(this_opt, name)) 301 - return 0; 302 - 303 - *ret = OPT_INTVAL(this_opt, name); 304 - return 1; 305 - } 306 - 307 - static __inline__ int get_opt_bool(const char *this_opt, const char *name, 308 - bool *ret) 309 - { 310 - if (!ret) 311 - return 0; 312 - 313 - if (OPT_EQUAL(this_opt, name)) { 314 - if (this_opt[strlen(name)] == '=') 315 - *ret = simple_strtoul(this_opt + strlen(name) + 1, 316 - NULL, 0); 317 - else 318 - *ret = 1; 319 - } else { 320 - if (OPT_EQUAL(this_opt, "no") && OPT_EQUAL(this_opt + 2, name)) 321 - *ret = 0; 322 - else 323 - return 0; 324 - } 325 - return 1; 326 - } 327 - 328 - static int __init intelfb_setup(char *options) 329 - { 330 - char *this_opt; 331 - 332 - DBG_MSG("intelfb_setup\n"); 333 - 334 - if (!options || !*options) { 335 - DBG_MSG("no options\n"); 336 - return 0; 337 - } else 338 - DBG_MSG("options: %s\n", options); 339 - 340 - /* 341 - * These are the built-in options analogous to the module parameters 342 - * defined above. 343 - * 344 - * The syntax is: 345 - * 346 - * video=intelfb:[mode][,<param>=<val>] ... 347 - * 348 - * e.g., 349 - * 350 - * video=intelfb:1024x768-16@75,accel=0 351 - */ 352 - 353 - while ((this_opt = strsep(&options, ","))) { 354 - if (!*this_opt) 355 - continue; 356 - if (get_opt_bool(this_opt, "accel", &accel)) 357 - ; 358 - else if (get_opt_int(this_opt, "vram", &vram)) 359 - ; 360 - else if (get_opt_bool(this_opt, "hwcursor", &hwcursor)) 361 - ; 362 - else if (get_opt_bool(this_opt, "mtrr", &mtrr)) 363 - ; 364 - else if (get_opt_bool(this_opt, "fixed", &fixed)) 365 - ; 366 - else if (get_opt_bool(this_opt, "init", &noinit)) 367 - noinit = !noinit; 368 - else if (OPT_EQUAL(this_opt, "mode=")) 369 - mode = get_opt_string(this_opt, "mode="); 370 - else 371 - mode = this_opt; 372 - } 373 - 374 - return 0; 375 - } 376 - 377 - #endif 378 - 379 - static int __init intelfb_init(void) 380 - { 381 - #ifndef MODULE 382 - char *option = NULL; 383 - #endif 384 - 385 - DBG_MSG("intelfb_init\n"); 386 - 387 - INF_MSG("Framebuffer driver for " 388 - "Intel(R) " SUPPORTED_CHIPSETS " chipsets\n"); 389 - INF_MSG("Version " INTELFB_VERSION "\n"); 390 - 391 - if (idonly) 392 - return -ENODEV; 393 - 394 - if (fb_modesetting_disabled("intelfb")) 395 - return -ENODEV; 396 - 397 - #ifndef MODULE 398 - if (fb_get_options("intelfb", &option)) 399 - return -ENODEV; 400 - intelfb_setup(option); 401 - #endif 402 - 403 - return pci_register_driver(&intelfb_driver); 404 - } 405 - 406 - static void __exit intelfb_exit(void) 407 - { 408 - DBG_MSG("intelfb_exit\n"); 409 - pci_unregister_driver(&intelfb_driver); 410 - } 411 - 412 - module_init(intelfb_init); 413 - module_exit(intelfb_exit); 414 - 415 - /*************************************************************** 416 - * driver init / cleanup * 417 - ***************************************************************/ 418 - 419 - static void cleanup(struct intelfb_info *dinfo) 420 - { 421 - DBG_MSG("cleanup\n"); 422 - 423 - if (!dinfo) 424 - return; 425 - 426 - intelfbhw_disable_irq(dinfo); 427 - 428 - fb_dealloc_cmap(&dinfo->info->cmap); 429 - kfree(dinfo->info->pixmap.addr); 430 - 431 - if (dinfo->registered) 432 - unregister_framebuffer(dinfo->info); 433 - 434 - arch_phys_wc_del(dinfo->wc_cookie); 435 - 436 - if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) { 437 - agp_unbind_memory(dinfo->gtt_fb_mem); 438 - agp_free_memory(dinfo->gtt_fb_mem); 439 - } 440 - if (dinfo->gtt_cursor_mem) { 441 - agp_unbind_memory(dinfo->gtt_cursor_mem); 442 - agp_free_memory(dinfo->gtt_cursor_mem); 443 - } 444 - if (dinfo->gtt_ring_mem) { 445 - agp_unbind_memory(dinfo->gtt_ring_mem); 446 - agp_free_memory(dinfo->gtt_ring_mem); 447 - } 448 - 449 - #ifdef CONFIG_FB_INTEL_I2C 450 - /* un-register I2C bus */ 451 - intelfb_delete_i2c_busses(dinfo); 452 - #endif 453 - 454 - if (dinfo->mmio_base) 455 - iounmap((void __iomem *)dinfo->mmio_base); 456 - if (dinfo->aperture.virtual) 457 - iounmap((void __iomem *)dinfo->aperture.virtual); 458 - 459 - if (dinfo->flag & INTELFB_MMIO_ACQUIRED) 460 - release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE); 461 - if (dinfo->flag & INTELFB_FB_ACQUIRED) 462 - release_mem_region(dinfo->aperture.physical, 463 - dinfo->aperture.size); 464 - framebuffer_release(dinfo->info); 465 - } 466 - 467 - #define bailout(dinfo) do { \ 468 - DBG_MSG("bailout\n"); \ 469 - cleanup(dinfo); \ 470 - INF_MSG("Not going to register framebuffer, exiting...\n"); \ 471 - return -ENODEV; \ 472 - } while (0) 473 - 474 - 475 - static int intelfb_pci_register(struct pci_dev *pdev, 476 - const struct pci_device_id *ent) 477 - { 478 - struct fb_info *info; 479 - struct intelfb_info *dinfo; 480 - int i, err, dvo; 481 - int aperture_size, stolen_size = 0; 482 - struct agp_kern_info gtt_info; 483 - int agp_memtype; 484 - const char *s; 485 - struct agp_bridge_data *bridge; 486 - int aperture_bar = 0; 487 - int mmio_bar = 1; 488 - int offset; 489 - 490 - DBG_MSG("intelfb_pci_register\n"); 491 - 492 - err = aperture_remove_conflicting_pci_devices(pdev, "intelfb"); 493 - if (err) 494 - return err; 495 - 496 - num_registered++; 497 - if (num_registered != 1) { 498 - ERR_MSG("Attempted to register %d devices " 499 - "(should be only 1).\n", num_registered); 500 - return -ENODEV; 501 - } 502 - 503 - info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev); 504 - if (!info) 505 - return -ENOMEM; 506 - 507 - if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { 508 - ERR_MSG("Could not allocate cmap for intelfb_info.\n"); 509 - goto err_out_cmap; 510 - } 511 - 512 - dinfo = info->par; 513 - dinfo->info = info; 514 - dinfo->fbops = &intel_fb_ops; 515 - dinfo->pdev = pdev; 516 - 517 - /* Reserve pixmap space. */ 518 - info->pixmap.addr = kzalloc(64 * 1024, GFP_KERNEL); 519 - if (info->pixmap.addr == NULL) { 520 - ERR_MSG("Cannot reserve pixmap memory.\n"); 521 - goto err_out_pixmap; 522 - } 523 - 524 - /* set early this option because it could be changed by tv encoder 525 - driver */ 526 - dinfo->fixed_mode = fixed; 527 - 528 - /* Enable device. */ 529 - if ((err = pci_enable_device(pdev))) { 530 - ERR_MSG("Cannot enable device.\n"); 531 - cleanup(dinfo); 532 - return -ENODEV; 533 - } 534 - 535 - /* Set base addresses. */ 536 - if ((ent->device == PCI_DEVICE_ID_INTEL_915G) || 537 - (ent->device == PCI_DEVICE_ID_INTEL_915GM) || 538 - (ent->device == PCI_DEVICE_ID_INTEL_945G) || 539 - (ent->device == PCI_DEVICE_ID_INTEL_945GM) || 540 - (ent->device == PCI_DEVICE_ID_INTEL_945GME) || 541 - (ent->device == PCI_DEVICE_ID_INTEL_965G) || 542 - (ent->device == PCI_DEVICE_ID_INTEL_965GM)) { 543 - 544 - aperture_bar = 2; 545 - mmio_bar = 0; 546 - } 547 - dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); 548 - dinfo->aperture.size = pci_resource_len(pdev, aperture_bar); 549 - dinfo->mmio_base_phys = pci_resource_start(pdev, mmio_bar); 550 - DBG_MSG("fb aperture: 0x%llx/0x%llx, MMIO region: 0x%llx/0x%llx\n", 551 - (unsigned long long)pci_resource_start(pdev, aperture_bar), 552 - (unsigned long long)pci_resource_len(pdev, aperture_bar), 553 - (unsigned long long)pci_resource_start(pdev, mmio_bar), 554 - (unsigned long long)pci_resource_len(pdev, mmio_bar)); 555 - 556 - /* Reserve the fb and MMIO regions */ 557 - if (!request_mem_region(dinfo->aperture.physical, dinfo->aperture.size, 558 - INTELFB_MODULE_NAME)) { 559 - ERR_MSG("Cannot reserve FB region.\n"); 560 - cleanup(dinfo); 561 - return -ENODEV; 562 - } 563 - 564 - dinfo->flag |= INTELFB_FB_ACQUIRED; 565 - 566 - if (!request_mem_region(dinfo->mmio_base_phys, 567 - INTEL_REG_SIZE, 568 - INTELFB_MODULE_NAME)) { 569 - ERR_MSG("Cannot reserve MMIO region.\n"); 570 - cleanup(dinfo); 571 - return -ENODEV; 572 - } 573 - 574 - dinfo->flag |= INTELFB_MMIO_ACQUIRED; 575 - 576 - /* Get the chipset info. */ 577 - dinfo->pci_chipset = pdev->device; 578 - 579 - if (intelfbhw_get_chipset(pdev, dinfo)) { 580 - cleanup(dinfo); 581 - return -ENODEV; 582 - } 583 - 584 - if (intelfbhw_get_memory(pdev, &aperture_size, &stolen_size)) { 585 - cleanup(dinfo); 586 - return -ENODEV; 587 - } 588 - 589 - INF_MSG("%02x:%02x.%d: %s, aperture size %dMB, " 590 - "stolen memory %dkB\n", 591 - pdev->bus->number, PCI_SLOT(pdev->devfn), 592 - PCI_FUNC(pdev->devfn), dinfo->name, 593 - BtoMB(aperture_size), BtoKB(stolen_size)); 594 - 595 - /* Set these from the options. */ 596 - dinfo->accel = accel; 597 - dinfo->hwcursor = hwcursor; 598 - 599 - if (NOACCEL_CHIPSET(dinfo) && dinfo->accel == 1) { 600 - INF_MSG("Acceleration is not supported for the %s chipset.\n", 601 - dinfo->name); 602 - dinfo->accel = 0; 603 - } 604 - 605 - /* Framebuffer parameters - Use all the stolen memory if >= vram */ 606 - if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) { 607 - dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size); 608 - dinfo->fbmem_gart = 0; 609 - } else { 610 - dinfo->fb.size = MB(vram); 611 - dinfo->fbmem_gart = 1; 612 - } 613 - 614 - /* Allocate space for the ring buffer and HW cursor if enabled. */ 615 - if (dinfo->accel) { 616 - dinfo->ring.size = RINGBUFFER_SIZE; 617 - dinfo->ring_tail_mask = dinfo->ring.size - 1; 618 - } 619 - if (dinfo->hwcursor) 620 - dinfo->cursor.size = HW_CURSOR_SIZE; 621 - 622 - /* Use agpgart to manage the GATT */ 623 - if (!(bridge = agp_backend_acquire(pdev))) { 624 - ERR_MSG("cannot acquire agp\n"); 625 - cleanup(dinfo); 626 - return -ENODEV; 627 - } 628 - 629 - /* get the current gatt info */ 630 - if (agp_copy_info(bridge, &gtt_info)) { 631 - ERR_MSG("cannot get agp info\n"); 632 - agp_backend_release(bridge); 633 - cleanup(dinfo); 634 - return -ENODEV; 635 - } 636 - 637 - if (MB(voffset) < stolen_size) 638 - offset = (stolen_size >> 12); 639 - else 640 - offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE; 641 - 642 - /* set the mem offsets - set them after the already used pages */ 643 - if (dinfo->accel) 644 - dinfo->ring.offset = offset + gtt_info.current_memory; 645 - if (dinfo->hwcursor) 646 - dinfo->cursor.offset = offset + 647 - + gtt_info.current_memory + (dinfo->ring.size >> 12); 648 - if (dinfo->fbmem_gart) 649 - dinfo->fb.offset = offset + 650 - + gtt_info.current_memory + (dinfo->ring.size >> 12) 651 - + (dinfo->cursor.size >> 12); 652 - 653 - /* Allocate memories (which aren't stolen) */ 654 - /* Map the fb and MMIO regions */ 655 - /* ioremap only up to the end of used aperture */ 656 - dinfo->aperture.virtual = (u8 __iomem *)ioremap_wc 657 - (dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12) 658 - + dinfo->fb.size); 659 - if (!dinfo->aperture.virtual) { 660 - ERR_MSG("Cannot remap FB region.\n"); 661 - agp_backend_release(bridge); 662 - cleanup(dinfo); 663 - return -ENODEV; 664 - } 665 - 666 - dinfo->mmio_base = 667 - (u8 __iomem *)ioremap(dinfo->mmio_base_phys, 668 - INTEL_REG_SIZE); 669 - if (!dinfo->mmio_base) { 670 - ERR_MSG("Cannot remap MMIO region.\n"); 671 - agp_backend_release(bridge); 672 - cleanup(dinfo); 673 - return -ENODEV; 674 - } 675 - 676 - if (dinfo->accel) { 677 - if (!(dinfo->gtt_ring_mem = 678 - agp_allocate_memory(bridge, dinfo->ring.size >> 12, 679 - AGP_NORMAL_MEMORY))) { 680 - ERR_MSG("cannot allocate ring buffer memory\n"); 681 - agp_backend_release(bridge); 682 - cleanup(dinfo); 683 - return -ENOMEM; 684 - } 685 - if (agp_bind_memory(dinfo->gtt_ring_mem, 686 - dinfo->ring.offset)) { 687 - ERR_MSG("cannot bind ring buffer memory\n"); 688 - agp_backend_release(bridge); 689 - cleanup(dinfo); 690 - return -EBUSY; 691 - } 692 - dinfo->ring.physical = dinfo->aperture.physical 693 - + (dinfo->ring.offset << 12); 694 - dinfo->ring.virtual = dinfo->aperture.virtual 695 - + (dinfo->ring.offset << 12); 696 - dinfo->ring_head = 0; 697 - } 698 - if (dinfo->hwcursor) { 699 - agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY 700 - : AGP_NORMAL_MEMORY; 701 - if (!(dinfo->gtt_cursor_mem = 702 - agp_allocate_memory(bridge, dinfo->cursor.size >> 12, 703 - agp_memtype))) { 704 - ERR_MSG("cannot allocate cursor memory\n"); 705 - agp_backend_release(bridge); 706 - cleanup(dinfo); 707 - return -ENOMEM; 708 - } 709 - if (agp_bind_memory(dinfo->gtt_cursor_mem, 710 - dinfo->cursor.offset)) { 711 - ERR_MSG("cannot bind cursor memory\n"); 712 - agp_backend_release(bridge); 713 - cleanup(dinfo); 714 - return -EBUSY; 715 - } 716 - if (dinfo->mobile) 717 - dinfo->cursor.physical 718 - = dinfo->gtt_cursor_mem->physical; 719 - else 720 - dinfo->cursor.physical = dinfo->aperture.physical 721 - + (dinfo->cursor.offset << 12); 722 - dinfo->cursor.virtual = dinfo->aperture.virtual 723 - + (dinfo->cursor.offset << 12); 724 - } 725 - if (dinfo->fbmem_gart) { 726 - if (!(dinfo->gtt_fb_mem = 727 - agp_allocate_memory(bridge, dinfo->fb.size >> 12, 728 - AGP_NORMAL_MEMORY))) { 729 - WRN_MSG("cannot allocate framebuffer memory - use " 730 - "the stolen one\n"); 731 - dinfo->fbmem_gart = 0; 732 - } 733 - if (agp_bind_memory(dinfo->gtt_fb_mem, 734 - dinfo->fb.offset)) { 735 - WRN_MSG("cannot bind framebuffer memory - use " 736 - "the stolen one\n"); 737 - dinfo->fbmem_gart = 0; 738 - } 739 - } 740 - 741 - /* update framebuffer memory parameters */ 742 - if (!dinfo->fbmem_gart) 743 - dinfo->fb.offset = 0; /* starts at offset 0 */ 744 - dinfo->fb.physical = dinfo->aperture.physical 745 - + (dinfo->fb.offset << 12); 746 - dinfo->fb.virtual = dinfo->aperture.virtual + (dinfo->fb.offset << 12); 747 - dinfo->fb_start = dinfo->fb.offset << 12; 748 - 749 - /* release agpgart */ 750 - agp_backend_release(bridge); 751 - 752 - if (mtrr) 753 - dinfo->wc_cookie = arch_phys_wc_add(dinfo->aperture.physical, 754 - dinfo->aperture.size); 755 - 756 - DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n", 757 - dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size, 758 - dinfo->fb.virtual); 759 - DBG_MSG("MMIO: 0x%x/0x%x (0x%p)\n", 760 - dinfo->mmio_base_phys, INTEL_REG_SIZE, 761 - dinfo->mmio_base); 762 - DBG_MSG("ring buffer: 0x%x/0x%x (0x%p)\n", 763 - dinfo->ring.physical, dinfo->ring.size, 764 - dinfo->ring.virtual); 765 - DBG_MSG("HW cursor: 0x%x/0x%x (0x%p) (offset 0x%x) (phys 0x%x)\n", 766 - dinfo->cursor.physical, dinfo->cursor.size, 767 - dinfo->cursor.virtual, dinfo->cursor.offset, 768 - dinfo->cursor.physical); 769 - 770 - DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d, " 771 - "noinit = %d\n", vram, accel, hwcursor, fixed, noinit); 772 - DBG_MSG("options: mode = \"%s\"\n", mode ? mode : ""); 773 - 774 - if (probeonly) 775 - bailout(dinfo); 776 - 777 - /* 778 - * Check if the LVDS port or any DVO ports are enabled. If so, 779 - * don't allow mode switching 780 - */ 781 - dvo = intelfbhw_check_non_crt(dinfo); 782 - if (dvo) { 783 - dinfo->fixed_mode = 1; 784 - WRN_MSG("Non-CRT device is enabled ( "); 785 - i = 0; 786 - while (dvo) { 787 - if (dvo & 1) { 788 - s = intelfbhw_dvo_to_string(1 << i); 789 - if (s) 790 - printk("%s ", s); 791 - } 792 - dvo >>= 1; 793 - ++i; 794 - } 795 - printk("). Disabling mode switching.\n"); 796 - } 797 - 798 - if (bailearly == 1) 799 - bailout(dinfo); 800 - 801 - if (FIXED_MODE(dinfo) && 802 - screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) { 803 - ERR_MSG("Video mode must be programmed at boot time.\n"); 804 - cleanup(dinfo); 805 - return -ENODEV; 806 - } 807 - 808 - if (bailearly == 2) 809 - bailout(dinfo); 810 - 811 - /* Initialise dinfo and related data. */ 812 - /* If an initial mode was programmed at boot time, get its details. */ 813 - if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) 814 - get_initial_mode(dinfo); 815 - 816 - if (bailearly == 3) 817 - bailout(dinfo); 818 - 819 - if (FIXED_MODE(dinfo)) /* remap fb address */ 820 - update_dinfo(dinfo, &dinfo->initial_var); 821 - 822 - if (bailearly == 4) 823 - bailout(dinfo); 824 - 825 - 826 - if (intelfb_set_fbinfo(dinfo)) { 827 - cleanup(dinfo); 828 - return -ENODEV; 829 - } 830 - 831 - if (bailearly == 5) 832 - bailout(dinfo); 833 - 834 - #ifdef CONFIG_FB_INTEL_I2C 835 - /* register I2C bus */ 836 - intelfb_create_i2c_busses(dinfo); 837 - #endif 838 - 839 - if (bailearly == 6) 840 - bailout(dinfo); 841 - 842 - pci_set_drvdata(pdev, dinfo); 843 - 844 - /* Save the initial register state. */ 845 - i = intelfbhw_read_hw_state(dinfo, &dinfo->save_state, 846 - bailearly > 6 ? bailearly - 6 : 0); 847 - if (i != 0) { 848 - DBG_MSG("intelfbhw_read_hw_state returned %d\n", i); 849 - bailout(dinfo); 850 - } 851 - 852 - intelfbhw_print_hw_state(dinfo, &dinfo->save_state); 853 - 854 - if (bailearly == 18) 855 - bailout(dinfo); 856 - 857 - /* read active pipe */ 858 - dinfo->pipe = intelfbhw_active_pipe(&dinfo->save_state); 859 - 860 - /* Cursor initialisation */ 861 - if (dinfo->hwcursor) { 862 - intelfbhw_cursor_init(dinfo); 863 - intelfbhw_cursor_reset(dinfo); 864 - } 865 - 866 - if (bailearly == 19) 867 - bailout(dinfo); 868 - 869 - /* 2d acceleration init */ 870 - if (dinfo->accel) 871 - intelfbhw_2d_start(dinfo); 872 - 873 - if (bailearly == 20) 874 - bailout(dinfo); 875 - 876 - if (noregister) 877 - bailout(dinfo); 878 - 879 - if (register_framebuffer(dinfo->info) < 0) { 880 - ERR_MSG("Cannot register framebuffer.\n"); 881 - cleanup(dinfo); 882 - return -ENODEV; 883 - } 884 - 885 - dinfo->registered = 1; 886 - dinfo->open = 0; 887 - 888 - init_waitqueue_head(&dinfo->vsync.wait); 889 - spin_lock_init(&dinfo->int_lock); 890 - dinfo->irq_flags = 0; 891 - dinfo->vsync.pan_display = 0; 892 - dinfo->vsync.pan_offset = 0; 893 - 894 - return 0; 895 - 896 - err_out_pixmap: 897 - fb_dealloc_cmap(&info->cmap); 898 - err_out_cmap: 899 - framebuffer_release(info); 900 - return -ENODEV; 901 - } 902 - 903 - static void intelfb_pci_unregister(struct pci_dev *pdev) 904 - { 905 - struct intelfb_info *dinfo = pci_get_drvdata(pdev); 906 - 907 - DBG_MSG("intelfb_pci_unregister\n"); 908 - 909 - if (!dinfo) 910 - return; 911 - 912 - cleanup(dinfo); 913 - } 914 - 915 - /*************************************************************** 916 - * helper functions * 917 - ***************************************************************/ 918 - 919 - __inline__ int intelfb_var_to_depth(const struct fb_var_screeninfo *var) 920 - { 921 - DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n", 922 - var->bits_per_pixel, var->green.length); 923 - 924 - switch (var->bits_per_pixel) { 925 - case 16: 926 - return (var->green.length == 6) ? 16 : 15; 927 - case 32: 928 - return 24; 929 - default: 930 - return var->bits_per_pixel; 931 - } 932 - } 933 - 934 - 935 - static __inline__ int var_to_refresh(const struct fb_var_screeninfo *var) 936 - { 937 - int xtot = var->xres + var->left_margin + var->right_margin + 938 - var->hsync_len; 939 - int ytot = var->yres + var->upper_margin + var->lower_margin + 940 - var->vsync_len; 941 - 942 - return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; 943 - } 944 - 945 - /*************************************************************** 946 - * Various initialisation functions * 947 - ***************************************************************/ 948 - 949 - static void get_initial_mode(struct intelfb_info *dinfo) 950 - { 951 - struct fb_var_screeninfo *var; 952 - int xtot, ytot; 953 - 954 - DBG_MSG("get_initial_mode\n"); 955 - 956 - dinfo->initial_vga = 1; 957 - dinfo->initial_fb_base = screen_info.lfb_base; 958 - dinfo->initial_video_ram = screen_info.lfb_size * KB(64); 959 - dinfo->initial_pitch = screen_info.lfb_linelength; 960 - 961 - var = &dinfo->initial_var; 962 - memset(var, 0, sizeof(*var)); 963 - var->xres = screen_info.lfb_width; 964 - var->yres = screen_info.lfb_height; 965 - var->bits_per_pixel = screen_info.lfb_depth; 966 - switch (screen_info.lfb_depth) { 967 - case 15: 968 - var->bits_per_pixel = 16; 969 - break; 970 - case 24: 971 - var->bits_per_pixel = 32; 972 - break; 973 - } 974 - 975 - DBG_MSG("Initial info: FB is 0x%x/0x%x (%d kByte)\n", 976 - dinfo->initial_fb_base, dinfo->initial_video_ram, 977 - BtoKB(dinfo->initial_video_ram)); 978 - 979 - DBG_MSG("Initial info: mode is %dx%d-%d (%d)\n", 980 - var->xres, var->yres, var->bits_per_pixel, 981 - dinfo->initial_pitch); 982 - 983 - /* Dummy timing values (assume 60Hz) */ 984 - var->left_margin = (var->xres / 8) & 0xf8; 985 - var->right_margin = 32; 986 - var->upper_margin = 16; 987 - var->lower_margin = 4; 988 - var->hsync_len = (var->xres / 8) & 0xf8; 989 - var->vsync_len = 4; 990 - 991 - xtot = var->xres + var->left_margin + 992 - var->right_margin + var->hsync_len; 993 - ytot = var->yres + var->upper_margin + 994 - var->lower_margin + var->vsync_len; 995 - var->pixclock = 10000000 / xtot * 1000 / ytot * 100 / 60; 996 - 997 - var->height = -1; 998 - var->width = -1; 999 - 1000 - if (var->bits_per_pixel > 8) { 1001 - var->red.offset = screen_info.red_pos; 1002 - var->red.length = screen_info.red_size; 1003 - var->green.offset = screen_info.green_pos; 1004 - var->green.length = screen_info.green_size; 1005 - var->blue.offset = screen_info.blue_pos; 1006 - var->blue.length = screen_info.blue_size; 1007 - var->transp.offset = screen_info.rsvd_pos; 1008 - var->transp.length = screen_info.rsvd_size; 1009 - } else { 1010 - var->red.length = 8; 1011 - var->green.length = 8; 1012 - var->blue.length = 8; 1013 - } 1014 - } 1015 - 1016 - static int intelfb_init_var(struct intelfb_info *dinfo) 1017 - { 1018 - struct fb_var_screeninfo *var; 1019 - int msrc = 0; 1020 - 1021 - DBG_MSG("intelfb_init_var\n"); 1022 - 1023 - var = &dinfo->info->var; 1024 - if (FIXED_MODE(dinfo)) { 1025 - memcpy(var, &dinfo->initial_var, 1026 - sizeof(struct fb_var_screeninfo)); 1027 - msrc = 5; 1028 - } else { 1029 - const u8 *edid_s = fb_firmware_edid(&dinfo->pdev->dev); 1030 - u8 *edid_d = NULL; 1031 - 1032 - if (edid_s) { 1033 - edid_d = kmemdup(edid_s, EDID_LENGTH, GFP_KERNEL); 1034 - 1035 - if (edid_d) { 1036 - fb_edid_to_monspecs(edid_d, 1037 - &dinfo->info->monspecs); 1038 - kfree(edid_d); 1039 - } 1040 - } 1041 - 1042 - if (mode) { 1043 - printk("intelfb: Looking for mode in private " 1044 - "database\n"); 1045 - msrc = fb_find_mode(var, dinfo->info, mode, 1046 - dinfo->info->monspecs.modedb, 1047 - dinfo->info->monspecs.modedb_len, 1048 - NULL, 0); 1049 - 1050 - if (msrc && msrc > 1) { 1051 - printk("intelfb: No mode in private database, " 1052 - "intelfb: looking for mode in global " 1053 - "database "); 1054 - msrc = fb_find_mode(var, dinfo->info, mode, 1055 - NULL, 0, NULL, 0); 1056 - 1057 - if (msrc) 1058 - msrc |= 8; 1059 - } 1060 - 1061 - } 1062 - 1063 - if (!msrc) 1064 - msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, 1065 - NULL, 0, NULL, 0); 1066 - } 1067 - 1068 - if (!msrc) { 1069 - ERR_MSG("Cannot find a suitable video mode.\n"); 1070 - return 1; 1071 - } 1072 - 1073 - INF_MSG("Initial video mode is %dx%d-%d@%d.\n", var->xres, var->yres, 1074 - var->bits_per_pixel, var_to_refresh(var)); 1075 - 1076 - DBG_MSG("Initial video mode is from %d.\n", msrc); 1077 - 1078 - #if ALLOCATE_FOR_PANNING 1079 - /* Allow use of half of the video ram for panning */ 1080 - var->xres_virtual = var->xres; 1081 - var->yres_virtual = 1082 - dinfo->fb.size / 2 / (var->bits_per_pixel * var->xres); 1083 - if (var->yres_virtual < var->yres) 1084 - var->yres_virtual = var->yres; 1085 - #else 1086 - var->yres_virtual = var->yres; 1087 - #endif 1088 - 1089 - if (dinfo->accel) 1090 - var->accel_flags |= FB_ACCELF_TEXT; 1091 - else 1092 - var->accel_flags &= ~FB_ACCELF_TEXT; 1093 - 1094 - return 0; 1095 - } 1096 - 1097 - static int intelfb_set_fbinfo(struct intelfb_info *dinfo) 1098 - { 1099 - struct fb_info *info = dinfo->info; 1100 - 1101 - DBG_MSG("intelfb_set_fbinfo\n"); 1102 - 1103 - info->fbops = &intel_fb_ops; 1104 - info->pseudo_palette = dinfo->pseudo_palette; 1105 - 1106 - info->pixmap.size = 64*1024; 1107 - info->pixmap.buf_align = 8; 1108 - info->pixmap.access_align = 32; 1109 - info->pixmap.flags = FB_PIXMAP_SYSTEM; 1110 - 1111 - if (intelfb_init_var(dinfo)) 1112 - return 1; 1113 - 1114 - info->pixmap.scan_align = 1; 1115 - strcpy(info->fix.id, dinfo->name); 1116 - info->fix.smem_start = dinfo->fb.physical; 1117 - info->fix.smem_len = dinfo->fb.size; 1118 - info->fix.type = FB_TYPE_PACKED_PIXELS; 1119 - info->fix.type_aux = 0; 1120 - info->fix.xpanstep = 8; 1121 - info->fix.ypanstep = 1; 1122 - info->fix.ywrapstep = 0; 1123 - info->fix.mmio_start = dinfo->mmio_base_phys; 1124 - info->fix.mmio_len = INTEL_REG_SIZE; 1125 - info->fix.accel = FB_ACCEL_I830; 1126 - update_dinfo(dinfo, &info->var); 1127 - 1128 - return 0; 1129 - } 1130 - 1131 - /* Update dinfo to match the active video mode. */ 1132 - static void update_dinfo(struct intelfb_info *dinfo, 1133 - struct fb_var_screeninfo *var) 1134 - { 1135 - DBG_MSG("update_dinfo\n"); 1136 - 1137 - dinfo->bpp = var->bits_per_pixel; 1138 - dinfo->depth = intelfb_var_to_depth(var); 1139 - dinfo->xres = var->xres; 1140 - dinfo->yres = var->xres; 1141 - dinfo->pixclock = var->pixclock; 1142 - 1143 - dinfo->info->fix.visual = dinfo->visual; 1144 - dinfo->info->fix.line_length = dinfo->pitch; 1145 - 1146 - switch (dinfo->bpp) { 1147 - case 8: 1148 - dinfo->visual = FB_VISUAL_PSEUDOCOLOR; 1149 - dinfo->pitch = var->xres_virtual; 1150 - break; 1151 - case 16: 1152 - dinfo->visual = FB_VISUAL_TRUECOLOR; 1153 - dinfo->pitch = var->xres_virtual * 2; 1154 - break; 1155 - case 32: 1156 - dinfo->visual = FB_VISUAL_TRUECOLOR; 1157 - dinfo->pitch = var->xres_virtual * 4; 1158 - break; 1159 - } 1160 - 1161 - /* Make sure the line length is a aligned correctly. */ 1162 - if (IS_I9XX(dinfo)) 1163 - dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT_I9XX); 1164 - else 1165 - dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); 1166 - 1167 - if (FIXED_MODE(dinfo)) 1168 - dinfo->pitch = dinfo->initial_pitch; 1169 - 1170 - dinfo->info->screen_base = (char __iomem *)dinfo->fb.virtual; 1171 - dinfo->info->fix.line_length = dinfo->pitch; 1172 - dinfo->info->fix.visual = dinfo->visual; 1173 - } 1174 - 1175 - /* fbops functions */ 1176 - 1177 - /*************************************************************** 1178 - * fbdev interface * 1179 - ***************************************************************/ 1180 - 1181 - static int intelfb_open(struct fb_info *info, int user) 1182 - { 1183 - struct intelfb_info *dinfo = GET_DINFO(info); 1184 - 1185 - if (user) 1186 - dinfo->open++; 1187 - 1188 - return 0; 1189 - } 1190 - 1191 - static int intelfb_release(struct fb_info *info, int user) 1192 - { 1193 - struct intelfb_info *dinfo = GET_DINFO(info); 1194 - 1195 - if (user) { 1196 - dinfo->open--; 1197 - msleep(1); 1198 - if (!dinfo->open) 1199 - intelfbhw_disable_irq(dinfo); 1200 - } 1201 - 1202 - return 0; 1203 - } 1204 - 1205 - static int intelfb_check_var(struct fb_var_screeninfo *var, 1206 - struct fb_info *info) 1207 - { 1208 - int change_var = 0; 1209 - struct fb_var_screeninfo v; 1210 - struct intelfb_info *dinfo; 1211 - static int first = 1; 1212 - int i; 1213 - /* Good pitches to allow tiling. Don't care about pitches < 1024. */ 1214 - static const int pitches[] = { 1215 - 128 * 8, 1216 - 128 * 16, 1217 - 128 * 32, 1218 - 128 * 64, 1219 - 0 1220 - }; 1221 - 1222 - DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags); 1223 - 1224 - dinfo = GET_DINFO(info); 1225 - 1226 - if (!var->pixclock) 1227 - return -EINVAL; 1228 - 1229 - /* update the pitch */ 1230 - if (intelfbhw_validate_mode(dinfo, var) != 0) 1231 - return -EINVAL; 1232 - 1233 - v = *var; 1234 - 1235 - for (i = 0; pitches[i] != 0; i++) { 1236 - if (pitches[i] >= v.xres_virtual) { 1237 - v.xres_virtual = pitches[i]; 1238 - break; 1239 - } 1240 - } 1241 - 1242 - /* Check for a supported bpp. */ 1243 - if (v.bits_per_pixel <= 8) 1244 - v.bits_per_pixel = 8; 1245 - else if (v.bits_per_pixel <= 16) { 1246 - if (v.bits_per_pixel == 16) 1247 - v.green.length = 6; 1248 - v.bits_per_pixel = 16; 1249 - } else if (v.bits_per_pixel <= 32) 1250 - v.bits_per_pixel = 32; 1251 - else 1252 - return -EINVAL; 1253 - 1254 - change_var = ((info->var.xres != var->xres) || 1255 - (info->var.yres != var->yres) || 1256 - (info->var.xres_virtual != var->xres_virtual) || 1257 - (info->var.yres_virtual != var->yres_virtual) || 1258 - (info->var.bits_per_pixel != var->bits_per_pixel) || 1259 - memcmp(&info->var.red, &var->red, sizeof(var->red)) || 1260 - memcmp(&info->var.green, &var->green, 1261 - sizeof(var->green)) || 1262 - memcmp(&info->var.blue, &var->blue, sizeof(var->blue))); 1263 - 1264 - if (FIXED_MODE(dinfo) && 1265 - (change_var || 1266 - var->yres_virtual > dinfo->initial_var.yres_virtual || 1267 - var->yres_virtual < dinfo->initial_var.yres || 1268 - var->xoffset || var->nonstd)) { 1269 - if (first) { 1270 - ERR_MSG("Changing the video mode is not supported.\n"); 1271 - first = 0; 1272 - } 1273 - return -EINVAL; 1274 - } 1275 - 1276 - switch (intelfb_var_to_depth(&v)) { 1277 - case 8: 1278 - v.red.offset = v.green.offset = v.blue.offset = 0; 1279 - v.red.length = v.green.length = v.blue.length = 8; 1280 - v.transp.offset = v.transp.length = 0; 1281 - break; 1282 - case 15: 1283 - v.red.offset = 10; 1284 - v.green.offset = 5; 1285 - v.blue.offset = 0; 1286 - v.red.length = v.green.length = v.blue.length = 5; 1287 - v.transp.offset = v.transp.length = 0; 1288 - break; 1289 - case 16: 1290 - v.red.offset = 11; 1291 - v.green.offset = 5; 1292 - v.blue.offset = 0; 1293 - v.red.length = 5; 1294 - v.green.length = 6; 1295 - v.blue.length = 5; 1296 - v.transp.offset = v.transp.length = 0; 1297 - break; 1298 - case 24: 1299 - v.red.offset = 16; 1300 - v.green.offset = 8; 1301 - v.blue.offset = 0; 1302 - v.red.length = v.green.length = v.blue.length = 8; 1303 - v.transp.offset = v.transp.length = 0; 1304 - break; 1305 - case 32: 1306 - v.red.offset = 16; 1307 - v.green.offset = 8; 1308 - v.blue.offset = 0; 1309 - v.red.length = v.green.length = v.blue.length = 8; 1310 - v.transp.offset = 24; 1311 - v.transp.length = 8; 1312 - break; 1313 - } 1314 - 1315 - if (v.xoffset > v.xres_virtual - v.xres) 1316 - v.xoffset = v.xres_virtual - v.xres; 1317 - if (v.yoffset > v.yres_virtual - v.yres) 1318 - v.yoffset = v.yres_virtual - v.yres; 1319 - 1320 - v.red.msb_right = v.green.msb_right = v.blue.msb_right = 1321 - v.transp.msb_right = 0; 1322 - 1323 - *var = v; 1324 - 1325 - return 0; 1326 - } 1327 - 1328 - static int intelfb_set_par(struct fb_info *info) 1329 - { 1330 - struct intelfb_hwstate *hw; 1331 - struct intelfb_info *dinfo = GET_DINFO(info); 1332 - 1333 - if (FIXED_MODE(dinfo)) { 1334 - ERR_MSG("Changing the video mode is not supported.\n"); 1335 - return -EINVAL; 1336 - } 1337 - 1338 - hw = kmalloc(sizeof(*hw), GFP_ATOMIC); 1339 - if (!hw) 1340 - return -ENOMEM; 1341 - 1342 - DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, 1343 - info->var.yres, info->var.bits_per_pixel); 1344 - 1345 - /* 1346 - * Disable VCO prior to timing register change. 1347 - */ 1348 - OUTREG(DPLL_A, INREG(DPLL_A) & ~DPLL_VCO_ENABLE); 1349 - 1350 - intelfb_blank(FB_BLANK_POWERDOWN, info); 1351 - 1352 - if (ACCEL(dinfo, info)) 1353 - intelfbhw_2d_stop(dinfo); 1354 - 1355 - memcpy(hw, &dinfo->save_state, sizeof(*hw)); 1356 - if (intelfbhw_mode_to_hw(dinfo, hw, &info->var)) 1357 - goto invalid_mode; 1358 - if (intelfbhw_program_mode(dinfo, hw, 0)) 1359 - goto invalid_mode; 1360 - 1361 - #if REGDUMP > 0 1362 - intelfbhw_read_hw_state(dinfo, hw, 0); 1363 - intelfbhw_print_hw_state(dinfo, hw); 1364 - #endif 1365 - 1366 - update_dinfo(dinfo, &info->var); 1367 - 1368 - if (ACCEL(dinfo, info)) 1369 - intelfbhw_2d_start(dinfo); 1370 - 1371 - intelfb_pan_display(&info->var, info); 1372 - 1373 - intelfb_blank(FB_BLANK_UNBLANK, info); 1374 - 1375 - if (ACCEL(dinfo, info)) { 1376 - info->flags = FBINFO_HWACCEL_YPAN | 1377 - FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1378 - FBINFO_HWACCEL_IMAGEBLIT; 1379 - } else 1380 - info->flags = FBINFO_HWACCEL_YPAN; 1381 - 1382 - kfree(hw); 1383 - return 0; 1384 - invalid_mode: 1385 - kfree(hw); 1386 - return -EINVAL; 1387 - } 1388 - 1389 - static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1390 - unsigned blue, unsigned transp, 1391 - struct fb_info *info) 1392 - { 1393 - struct intelfb_info *dinfo = GET_DINFO(info); 1394 - 1395 - #if VERBOSE > 0 1396 - DBG_MSG("intelfb_setcolreg: regno %d, depth %d\n", regno, dinfo->depth); 1397 - #endif 1398 - 1399 - if (regno > 255) 1400 - return 1; 1401 - 1402 - if (dinfo->depth == 8) { 1403 - red >>= 8; 1404 - green >>= 8; 1405 - blue >>= 8; 1406 - 1407 - intelfbhw_setcolreg(dinfo, regno, red, green, blue, 1408 - transp); 1409 - } 1410 - 1411 - if (regno < 16) { 1412 - switch (dinfo->depth) { 1413 - case 15: 1414 - dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) | 1415 - ((green & 0xf800) >> 6) | 1416 - ((blue & 0xf800) >> 11); 1417 - break; 1418 - case 16: 1419 - dinfo->pseudo_palette[regno] = (red & 0xf800) | 1420 - ((green & 0xfc00) >> 5) | 1421 - ((blue & 0xf800) >> 11); 1422 - break; 1423 - case 24: 1424 - dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) | 1425 - (green & 0xff00) | 1426 - ((blue & 0xff00) >> 8); 1427 - break; 1428 - } 1429 - } 1430 - 1431 - return 0; 1432 - } 1433 - 1434 - static int intelfb_blank(int blank, struct fb_info *info) 1435 - { 1436 - intelfbhw_do_blank(blank, info); 1437 - return 0; 1438 - } 1439 - 1440 - static int intelfb_pan_display(struct fb_var_screeninfo *var, 1441 - struct fb_info *info) 1442 - { 1443 - intelfbhw_pan_display(var, info); 1444 - return 0; 1445 - } 1446 - 1447 - /* When/if we have our own ioctls. */ 1448 - static int intelfb_ioctl(struct fb_info *info, unsigned int cmd, 1449 - unsigned long arg) 1450 - { 1451 - int retval = 0; 1452 - struct intelfb_info *dinfo = GET_DINFO(info); 1453 - u32 pipe = 0; 1454 - 1455 - switch (cmd) { 1456 - case FBIO_WAITFORVSYNC: 1457 - if (get_user(pipe, (__u32 __user *)arg)) 1458 - return -EFAULT; 1459 - 1460 - retval = intelfbhw_wait_for_vsync(dinfo, pipe); 1461 - break; 1462 - default: 1463 - break; 1464 - } 1465 - 1466 - return retval; 1467 - } 1468 - 1469 - static void intelfb_fillrect (struct fb_info *info, 1470 - const struct fb_fillrect *rect) 1471 - { 1472 - struct intelfb_info *dinfo = GET_DINFO(info); 1473 - u32 rop, color; 1474 - 1475 - #if VERBOSE > 0 1476 - DBG_MSG("intelfb_fillrect\n"); 1477 - #endif 1478 - 1479 - if (!ACCEL(dinfo, info) || dinfo->depth == 4) { 1480 - cfb_fillrect(info, rect); 1481 - return; 1482 - } 1483 - 1484 - if (rect->rop == ROP_COPY) 1485 - rop = PAT_ROP_GXCOPY; 1486 - else /* ROP_XOR */ 1487 - rop = PAT_ROP_GXXOR; 1488 - 1489 - if (dinfo->depth != 8) 1490 - color = dinfo->pseudo_palette[rect->color]; 1491 - else 1492 - color = rect->color; 1493 - 1494 - intelfbhw_do_fillrect(dinfo, rect->dx, rect->dy, 1495 - rect->width, rect->height, color, 1496 - dinfo->pitch, info->var.bits_per_pixel, 1497 - rop); 1498 - } 1499 - 1500 - static void intelfb_copyarea(struct fb_info *info, 1501 - const struct fb_copyarea *region) 1502 - { 1503 - struct intelfb_info *dinfo = GET_DINFO(info); 1504 - 1505 - #if VERBOSE > 0 1506 - DBG_MSG("intelfb_copyarea\n"); 1507 - #endif 1508 - 1509 - if (!ACCEL(dinfo, info) || dinfo->depth == 4) { 1510 - cfb_copyarea(info, region); 1511 - return; 1512 - } 1513 - 1514 - intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx, 1515 - region->dy, region->width, region->height, 1516 - dinfo->pitch, info->var.bits_per_pixel); 1517 - } 1518 - 1519 - static void intelfb_imageblit(struct fb_info *info, 1520 - const struct fb_image *image) 1521 - { 1522 - struct intelfb_info *dinfo = GET_DINFO(info); 1523 - u32 fgcolor, bgcolor; 1524 - 1525 - #if VERBOSE > 0 1526 - DBG_MSG("intelfb_imageblit\n"); 1527 - #endif 1528 - 1529 - if (!ACCEL(dinfo, info) || dinfo->depth == 4 1530 - || image->depth != 1) { 1531 - cfb_imageblit(info, image); 1532 - return; 1533 - } 1534 - 1535 - if (dinfo->depth != 8) { 1536 - fgcolor = dinfo->pseudo_palette[image->fg_color]; 1537 - bgcolor = dinfo->pseudo_palette[image->bg_color]; 1538 - } else { 1539 - fgcolor = image->fg_color; 1540 - bgcolor = image->bg_color; 1541 - } 1542 - 1543 - if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width, 1544 - image->height, image->data, 1545 - image->dx, image->dy, 1546 - dinfo->pitch, info->var.bits_per_pixel)) { 1547 - cfb_imageblit(info, image); 1548 - return; 1549 - } 1550 - } 1551 - 1552 - static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1553 - { 1554 - struct intelfb_info *dinfo = GET_DINFO(info); 1555 - u32 physical; 1556 - #if VERBOSE > 0 1557 - DBG_MSG("intelfb_cursor\n"); 1558 - #endif 1559 - 1560 - if (!dinfo->hwcursor) 1561 - return -ENODEV; 1562 - 1563 - intelfbhw_cursor_hide(dinfo); 1564 - 1565 - /* If XFree killed the cursor - restore it */ 1566 - physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical : 1567 - (dinfo->cursor.offset << 12); 1568 - 1569 - if (INREG(CURSOR_A_BASEADDR) != physical) { 1570 - u32 fg, bg; 1571 - 1572 - DBG_MSG("the cursor was killed - restore it !!\n"); 1573 - DBG_MSG("size %d, %d pos %d, %d\n", 1574 - cursor->image.width, cursor->image.height, 1575 - cursor->image.dx, cursor->image.dy); 1576 - 1577 - intelfbhw_cursor_init(dinfo); 1578 - intelfbhw_cursor_reset(dinfo); 1579 - intelfbhw_cursor_setpos(dinfo, cursor->image.dx, 1580 - cursor->image.dy); 1581 - 1582 - if (dinfo->depth != 8) { 1583 - fg =dinfo->pseudo_palette[cursor->image.fg_color]; 1584 - bg =dinfo->pseudo_palette[cursor->image.bg_color]; 1585 - } else { 1586 - fg = cursor->image.fg_color; 1587 - bg = cursor->image.bg_color; 1588 - } 1589 - intelfbhw_cursor_setcolor(dinfo, bg, fg); 1590 - intelfbhw_cursor_load(dinfo, cursor->image.width, 1591 - cursor->image.height, 1592 - dinfo->cursor_src); 1593 - 1594 - if (cursor->enable) 1595 - intelfbhw_cursor_show(dinfo); 1596 - return 0; 1597 - } 1598 - 1599 - if (cursor->set & FB_CUR_SETPOS) { 1600 - u32 dx, dy; 1601 - 1602 - dx = cursor->image.dx - info->var.xoffset; 1603 - dy = cursor->image.dy - info->var.yoffset; 1604 - 1605 - intelfbhw_cursor_setpos(dinfo, dx, dy); 1606 - } 1607 - 1608 - if (cursor->set & FB_CUR_SETSIZE) { 1609 - if (cursor->image.width > 64 || cursor->image.height > 64) 1610 - return -ENXIO; 1611 - 1612 - intelfbhw_cursor_reset(dinfo); 1613 - } 1614 - 1615 - if (cursor->set & FB_CUR_SETCMAP) { 1616 - u32 fg, bg; 1617 - 1618 - if (dinfo->depth != 8) { 1619 - fg = dinfo->pseudo_palette[cursor->image.fg_color]; 1620 - bg = dinfo->pseudo_palette[cursor->image.bg_color]; 1621 - } else { 1622 - fg = cursor->image.fg_color; 1623 - bg = cursor->image.bg_color; 1624 - } 1625 - 1626 - intelfbhw_cursor_setcolor(dinfo, bg, fg); 1627 - } 1628 - 1629 - if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) { 1630 - u32 s_pitch = (ROUND_UP_TO(cursor->image.width, 8) / 8); 1631 - u32 size = s_pitch * cursor->image.height; 1632 - u8 *dat = (u8 *) cursor->image.data; 1633 - u8 *msk = (u8 *) cursor->mask; 1634 - u8 src[64]; 1635 - u32 i; 1636 - 1637 - if (cursor->image.depth != 1) 1638 - return -ENXIO; 1639 - 1640 - switch (cursor->rop) { 1641 - case ROP_XOR: 1642 - for (i = 0; i < size; i++) 1643 - src[i] = dat[i] ^ msk[i]; 1644 - break; 1645 - case ROP_COPY: 1646 - default: 1647 - for (i = 0; i < size; i++) 1648 - src[i] = dat[i] & msk[i]; 1649 - break; 1650 - } 1651 - 1652 - /* save the bitmap to restore it when XFree will 1653 - make the cursor dirty */ 1654 - memcpy(dinfo->cursor_src, src, size); 1655 - 1656 - intelfbhw_cursor_load(dinfo, cursor->image.width, 1657 - cursor->image.height, src); 1658 - } 1659 - 1660 - if (cursor->enable) 1661 - intelfbhw_cursor_show(dinfo); 1662 - 1663 - return 0; 1664 - } 1665 - 1666 - static int intelfb_sync(struct fb_info *info) 1667 - { 1668 - struct intelfb_info *dinfo = GET_DINFO(info); 1669 - 1670 - #if VERBOSE > 0 1671 - DBG_MSG("intelfb_sync\n"); 1672 - #endif 1673 - 1674 - if (dinfo->ring_lockup) 1675 - return 0; 1676 - 1677 - intelfbhw_do_sync(dinfo); 1678 - return 0; 1679 - } 1680 -
-2115
drivers/video/fbdev/intelfb/intelfbhw.c
··· 1 - /* 2 - * intelfb 3 - * 4 - * Linux framebuffer driver for Intel(R) 865G integrated graphics chips. 5 - * 6 - * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> 7 - * 2004 Sylvain Meyer 8 - * 9 - * This driver consists of two parts. The first part (intelfbdrv.c) provides 10 - * the basic fbdev interfaces, is derived in part from the radeonfb and 11 - * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c) 12 - * provides the code to program the hardware. Most of it is derived from 13 - * the i810/i830 XFree86 driver. The HW-specific code is covered here 14 - * under a dual license (GPL and MIT/XFree86 license). 15 - * 16 - * Author: David Dawes 17 - * 18 - */ 19 - 20 - /* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */ 21 - 22 - #include <linux/module.h> 23 - #include <linux/kernel.h> 24 - #include <linux/errno.h> 25 - #include <linux/string.h> 26 - #include <linux/mm.h> 27 - #include <linux/delay.h> 28 - #include <linux/fb.h> 29 - #include <linux/ioport.h> 30 - #include <linux/init.h> 31 - #include <linux/pci.h> 32 - #include <linux/vmalloc.h> 33 - #include <linux/pagemap.h> 34 - #include <linux/interrupt.h> 35 - 36 - #include <asm/io.h> 37 - 38 - #include "intelfb.h" 39 - #include "intelfbhw.h" 40 - 41 - struct pll_min_max { 42 - int min_m, max_m, min_m1, max_m1; 43 - int min_m2, max_m2, min_n, max_n; 44 - int min_p, max_p, min_p1, max_p1; 45 - int min_vco, max_vco, p_transition_clk, ref_clk; 46 - int p_inc_lo, p_inc_hi; 47 - }; 48 - 49 - #define PLLS_I8xx 0 50 - #define PLLS_I9xx 1 51 - #define PLLS_MAX 2 52 - 53 - static struct pll_min_max plls[PLLS_MAX] = { 54 - { 108, 140, 18, 26, 55 - 6, 16, 3, 16, 56 - 4, 128, 0, 31, 57 - 930000, 1400000, 165000, 48000, 58 - 4, 2 }, /* I8xx */ 59 - 60 - { 75, 120, 10, 20, 61 - 5, 9, 4, 7, 62 - 5, 80, 1, 8, 63 - 1400000, 2800000, 200000, 96000, 64 - 10, 5 } /* I9xx */ 65 - }; 66 - 67 - int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo) 68 - { 69 - u32 tmp; 70 - if (!pdev || !dinfo) 71 - return 1; 72 - 73 - switch (pdev->device) { 74 - case PCI_DEVICE_ID_INTEL_830M: 75 - dinfo->name = "Intel(R) 830M"; 76 - dinfo->chipset = INTEL_830M; 77 - dinfo->mobile = 1; 78 - dinfo->pll_index = PLLS_I8xx; 79 - return 0; 80 - case PCI_DEVICE_ID_INTEL_845G: 81 - dinfo->name = "Intel(R) 845G"; 82 - dinfo->chipset = INTEL_845G; 83 - dinfo->mobile = 0; 84 - dinfo->pll_index = PLLS_I8xx; 85 - return 0; 86 - case PCI_DEVICE_ID_INTEL_854: 87 - dinfo->mobile = 1; 88 - dinfo->name = "Intel(R) 854"; 89 - dinfo->chipset = INTEL_854; 90 - return 0; 91 - case PCI_DEVICE_ID_INTEL_85XGM: 92 - tmp = 0; 93 - dinfo->mobile = 1; 94 - dinfo->pll_index = PLLS_I8xx; 95 - pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp); 96 - switch ((tmp >> INTEL_85X_VARIANT_SHIFT) & 97 - INTEL_85X_VARIANT_MASK) { 98 - case INTEL_VAR_855GME: 99 - dinfo->name = "Intel(R) 855GME"; 100 - dinfo->chipset = INTEL_855GME; 101 - return 0; 102 - case INTEL_VAR_855GM: 103 - dinfo->name = "Intel(R) 855GM"; 104 - dinfo->chipset = INTEL_855GM; 105 - return 0; 106 - case INTEL_VAR_852GME: 107 - dinfo->name = "Intel(R) 852GME"; 108 - dinfo->chipset = INTEL_852GME; 109 - return 0; 110 - case INTEL_VAR_852GM: 111 - dinfo->name = "Intel(R) 852GM"; 112 - dinfo->chipset = INTEL_852GM; 113 - return 0; 114 - default: 115 - dinfo->name = "Intel(R) 852GM/855GM"; 116 - dinfo->chipset = INTEL_85XGM; 117 - return 0; 118 - } 119 - break; 120 - case PCI_DEVICE_ID_INTEL_865G: 121 - dinfo->name = "Intel(R) 865G"; 122 - dinfo->chipset = INTEL_865G; 123 - dinfo->mobile = 0; 124 - dinfo->pll_index = PLLS_I8xx; 125 - return 0; 126 - case PCI_DEVICE_ID_INTEL_915G: 127 - dinfo->name = "Intel(R) 915G"; 128 - dinfo->chipset = INTEL_915G; 129 - dinfo->mobile = 0; 130 - dinfo->pll_index = PLLS_I9xx; 131 - return 0; 132 - case PCI_DEVICE_ID_INTEL_915GM: 133 - dinfo->name = "Intel(R) 915GM"; 134 - dinfo->chipset = INTEL_915GM; 135 - dinfo->mobile = 1; 136 - dinfo->pll_index = PLLS_I9xx; 137 - return 0; 138 - case PCI_DEVICE_ID_INTEL_945G: 139 - dinfo->name = "Intel(R) 945G"; 140 - dinfo->chipset = INTEL_945G; 141 - dinfo->mobile = 0; 142 - dinfo->pll_index = PLLS_I9xx; 143 - return 0; 144 - case PCI_DEVICE_ID_INTEL_945GM: 145 - dinfo->name = "Intel(R) 945GM"; 146 - dinfo->chipset = INTEL_945GM; 147 - dinfo->mobile = 1; 148 - dinfo->pll_index = PLLS_I9xx; 149 - return 0; 150 - case PCI_DEVICE_ID_INTEL_945GME: 151 - dinfo->name = "Intel(R) 945GME"; 152 - dinfo->chipset = INTEL_945GME; 153 - dinfo->mobile = 1; 154 - dinfo->pll_index = PLLS_I9xx; 155 - return 0; 156 - case PCI_DEVICE_ID_INTEL_965G: 157 - dinfo->name = "Intel(R) 965G"; 158 - dinfo->chipset = INTEL_965G; 159 - dinfo->mobile = 0; 160 - dinfo->pll_index = PLLS_I9xx; 161 - return 0; 162 - case PCI_DEVICE_ID_INTEL_965GM: 163 - dinfo->name = "Intel(R) 965GM"; 164 - dinfo->chipset = INTEL_965GM; 165 - dinfo->mobile = 1; 166 - dinfo->pll_index = PLLS_I9xx; 167 - return 0; 168 - default: 169 - return 1; 170 - } 171 - } 172 - 173 - int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, 174 - int *stolen_size) 175 - { 176 - struct pci_dev *bridge_dev; 177 - u16 tmp; 178 - int stolen_overhead; 179 - 180 - if (!pdev || !aperture_size || !stolen_size) 181 - return 1; 182 - 183 - /* Find the bridge device. It is always 0:0.0 */ 184 - bridge_dev = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus), 0, 185 - PCI_DEVFN(0, 0)); 186 - if (!bridge_dev) { 187 - ERR_MSG("cannot find bridge device\n"); 188 - return 1; 189 - } 190 - 191 - /* Get the fb aperture size and "stolen" memory amount. */ 192 - tmp = 0; 193 - pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); 194 - pci_dev_put(bridge_dev); 195 - 196 - switch (pdev->device) { 197 - case PCI_DEVICE_ID_INTEL_915G: 198 - case PCI_DEVICE_ID_INTEL_915GM: 199 - case PCI_DEVICE_ID_INTEL_945G: 200 - case PCI_DEVICE_ID_INTEL_945GM: 201 - case PCI_DEVICE_ID_INTEL_945GME: 202 - case PCI_DEVICE_ID_INTEL_965G: 203 - case PCI_DEVICE_ID_INTEL_965GM: 204 - /* 205 - * 915, 945 and 965 chipsets support 64MB, 128MB or 256MB 206 - * aperture. Determine size from PCI resource length. 207 - */ 208 - *aperture_size = pci_resource_len(pdev, 2); 209 - break; 210 - default: 211 - if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) 212 - *aperture_size = MB(64); 213 - else 214 - *aperture_size = MB(128); 215 - break; 216 - } 217 - 218 - /* Stolen memory size is reduced by the GTT and the popup. 219 - GTT is 1K per MB of aperture size, and popup is 4K. */ 220 - stolen_overhead = (*aperture_size / MB(1)) + 4; 221 - switch(pdev->device) { 222 - case PCI_DEVICE_ID_INTEL_830M: 223 - case PCI_DEVICE_ID_INTEL_845G: 224 - switch (tmp & INTEL_830_GMCH_GMS_MASK) { 225 - case INTEL_830_GMCH_GMS_STOLEN_512: 226 - *stolen_size = KB(512) - KB(stolen_overhead); 227 - return 0; 228 - case INTEL_830_GMCH_GMS_STOLEN_1024: 229 - *stolen_size = MB(1) - KB(stolen_overhead); 230 - return 0; 231 - case INTEL_830_GMCH_GMS_STOLEN_8192: 232 - *stolen_size = MB(8) - KB(stolen_overhead); 233 - return 0; 234 - case INTEL_830_GMCH_GMS_LOCAL: 235 - ERR_MSG("only local memory found\n"); 236 - return 1; 237 - case INTEL_830_GMCH_GMS_DISABLED: 238 - ERR_MSG("video memory is disabled\n"); 239 - return 1; 240 - default: 241 - ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n", 242 - tmp & INTEL_830_GMCH_GMS_MASK); 243 - return 1; 244 - } 245 - break; 246 - default: 247 - switch (tmp & INTEL_855_GMCH_GMS_MASK) { 248 - case INTEL_855_GMCH_GMS_STOLEN_1M: 249 - *stolen_size = MB(1) - KB(stolen_overhead); 250 - return 0; 251 - case INTEL_855_GMCH_GMS_STOLEN_4M: 252 - *stolen_size = MB(4) - KB(stolen_overhead); 253 - return 0; 254 - case INTEL_855_GMCH_GMS_STOLEN_8M: 255 - *stolen_size = MB(8) - KB(stolen_overhead); 256 - return 0; 257 - case INTEL_855_GMCH_GMS_STOLEN_16M: 258 - *stolen_size = MB(16) - KB(stolen_overhead); 259 - return 0; 260 - case INTEL_855_GMCH_GMS_STOLEN_32M: 261 - *stolen_size = MB(32) - KB(stolen_overhead); 262 - return 0; 263 - case INTEL_915G_GMCH_GMS_STOLEN_48M: 264 - *stolen_size = MB(48) - KB(stolen_overhead); 265 - return 0; 266 - case INTEL_915G_GMCH_GMS_STOLEN_64M: 267 - *stolen_size = MB(64) - KB(stolen_overhead); 268 - return 0; 269 - case INTEL_855_GMCH_GMS_DISABLED: 270 - ERR_MSG("video memory is disabled\n"); 271 - return 0; 272 - default: 273 - ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n", 274 - tmp & INTEL_855_GMCH_GMS_MASK); 275 - return 1; 276 - } 277 - } 278 - } 279 - 280 - int intelfbhw_check_non_crt(struct intelfb_info *dinfo) 281 - { 282 - int dvo = 0; 283 - 284 - if (INREG(LVDS) & PORT_ENABLE) 285 - dvo |= LVDS_PORT; 286 - if (INREG(DVOA) & PORT_ENABLE) 287 - dvo |= DVOA_PORT; 288 - if (INREG(DVOB) & PORT_ENABLE) 289 - dvo |= DVOB_PORT; 290 - if (INREG(DVOC) & PORT_ENABLE) 291 - dvo |= DVOC_PORT; 292 - 293 - return dvo; 294 - } 295 - 296 - const char * intelfbhw_dvo_to_string(int dvo) 297 - { 298 - if (dvo & DVOA_PORT) 299 - return "DVO port A"; 300 - else if (dvo & DVOB_PORT) 301 - return "DVO port B"; 302 - else if (dvo & DVOC_PORT) 303 - return "DVO port C"; 304 - else if (dvo & LVDS_PORT) 305 - return "LVDS port"; 306 - else 307 - return NULL; 308 - } 309 - 310 - 311 - int intelfbhw_validate_mode(struct intelfb_info *dinfo, 312 - struct fb_var_screeninfo *var) 313 - { 314 - int bytes_per_pixel; 315 - int tmp; 316 - 317 - #if VERBOSE > 0 318 - DBG_MSG("intelfbhw_validate_mode\n"); 319 - #endif 320 - 321 - bytes_per_pixel = var->bits_per_pixel / 8; 322 - if (bytes_per_pixel == 3) 323 - bytes_per_pixel = 4; 324 - 325 - /* Check if enough video memory. */ 326 - tmp = var->yres_virtual * var->xres_virtual * bytes_per_pixel; 327 - if (tmp > dinfo->fb.size) { 328 - WRN_MSG("Not enough video ram for mode " 329 - "(%d KByte vs %d KByte).\n", 330 - BtoKB(tmp), BtoKB(dinfo->fb.size)); 331 - return 1; 332 - } 333 - 334 - /* Check if x/y limits are OK. */ 335 - if (var->xres - 1 > HACTIVE_MASK) { 336 - WRN_MSG("X resolution too large (%d vs %d).\n", 337 - var->xres, HACTIVE_MASK + 1); 338 - return 1; 339 - } 340 - if (var->yres - 1 > VACTIVE_MASK) { 341 - WRN_MSG("Y resolution too large (%d vs %d).\n", 342 - var->yres, VACTIVE_MASK + 1); 343 - return 1; 344 - } 345 - if (var->xres < 4) { 346 - WRN_MSG("X resolution too small (%d vs 4).\n", var->xres); 347 - return 1; 348 - } 349 - if (var->yres < 4) { 350 - WRN_MSG("Y resolution too small (%d vs 4).\n", var->yres); 351 - return 1; 352 - } 353 - 354 - /* Check for doublescan modes. */ 355 - if (var->vmode & FB_VMODE_DOUBLE) { 356 - WRN_MSG("Mode is double-scan.\n"); 357 - return 1; 358 - } 359 - 360 - if ((var->vmode & FB_VMODE_INTERLACED) && (var->yres & 1)) { 361 - WRN_MSG("Odd number of lines in interlaced mode\n"); 362 - return 1; 363 - } 364 - 365 - /* Check if clock is OK. */ 366 - tmp = 1000000000 / var->pixclock; 367 - if (tmp < MIN_CLOCK) { 368 - WRN_MSG("Pixel clock is too low (%d MHz vs %d MHz).\n", 369 - (tmp + 500) / 1000, MIN_CLOCK / 1000); 370 - return 1; 371 - } 372 - if (tmp > MAX_CLOCK) { 373 - WRN_MSG("Pixel clock is too high (%d MHz vs %d MHz).\n", 374 - (tmp + 500) / 1000, MAX_CLOCK / 1000); 375 - return 1; 376 - } 377 - 378 - return 0; 379 - } 380 - 381 - int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 382 - { 383 - struct intelfb_info *dinfo = GET_DINFO(info); 384 - u32 offset, xoffset, yoffset; 385 - 386 - #if VERBOSE > 0 387 - DBG_MSG("intelfbhw_pan_display\n"); 388 - #endif 389 - 390 - xoffset = ROUND_DOWN_TO(var->xoffset, 8); 391 - yoffset = var->yoffset; 392 - 393 - if ((xoffset + info->var.xres > info->var.xres_virtual) || 394 - (yoffset + info->var.yres > info->var.yres_virtual)) 395 - return -EINVAL; 396 - 397 - offset = (yoffset * dinfo->pitch) + 398 - (xoffset * info->var.bits_per_pixel) / 8; 399 - 400 - offset += dinfo->fb.offset << 12; 401 - 402 - dinfo->vsync.pan_offset = offset; 403 - if ((var->activate & FB_ACTIVATE_VBL) && 404 - !intelfbhw_enable_irq(dinfo)) 405 - dinfo->vsync.pan_display = 1; 406 - else { 407 - dinfo->vsync.pan_display = 0; 408 - OUTREG(DSPABASE, offset); 409 - } 410 - 411 - return 0; 412 - } 413 - 414 - /* Blank the screen. */ 415 - void intelfbhw_do_blank(int blank, struct fb_info *info) 416 - { 417 - struct intelfb_info *dinfo = GET_DINFO(info); 418 - u32 tmp; 419 - 420 - #if VERBOSE > 0 421 - DBG_MSG("intelfbhw_do_blank: blank is %d\n", blank); 422 - #endif 423 - 424 - /* Turn plane A on or off */ 425 - tmp = INREG(DSPACNTR); 426 - if (blank) 427 - tmp &= ~DISPPLANE_PLANE_ENABLE; 428 - else 429 - tmp |= DISPPLANE_PLANE_ENABLE; 430 - OUTREG(DSPACNTR, tmp); 431 - /* Flush */ 432 - tmp = INREG(DSPABASE); 433 - OUTREG(DSPABASE, tmp); 434 - 435 - /* Turn off/on the HW cursor */ 436 - #if VERBOSE > 0 437 - DBG_MSG("cursor_on is %d\n", dinfo->cursor_on); 438 - #endif 439 - if (dinfo->cursor_on) { 440 - if (blank) 441 - intelfbhw_cursor_hide(dinfo); 442 - else 443 - intelfbhw_cursor_show(dinfo); 444 - dinfo->cursor_on = 1; 445 - } 446 - dinfo->cursor_blanked = blank; 447 - 448 - /* Set DPMS level */ 449 - tmp = INREG(ADPA) & ~ADPA_DPMS_CONTROL_MASK; 450 - switch (blank) { 451 - case FB_BLANK_UNBLANK: 452 - case FB_BLANK_NORMAL: 453 - tmp |= ADPA_DPMS_D0; 454 - break; 455 - case FB_BLANK_VSYNC_SUSPEND: 456 - tmp |= ADPA_DPMS_D1; 457 - break; 458 - case FB_BLANK_HSYNC_SUSPEND: 459 - tmp |= ADPA_DPMS_D2; 460 - break; 461 - case FB_BLANK_POWERDOWN: 462 - tmp |= ADPA_DPMS_D3; 463 - break; 464 - } 465 - OUTREG(ADPA, tmp); 466 - 467 - return; 468 - } 469 - 470 - 471 - /* Check which pipe is connected to an active display plane. */ 472 - int intelfbhw_active_pipe(const struct intelfb_hwstate *hw) 473 - { 474 - int pipe = -1; 475 - 476 - /* keep old default behaviour - prefer PIPE_A */ 477 - if (hw->disp_b_ctrl & DISPPLANE_PLANE_ENABLE) { 478 - pipe = (hw->disp_b_ctrl >> DISPPLANE_SEL_PIPE_SHIFT); 479 - pipe &= PIPE_MASK; 480 - if (unlikely(pipe == PIPE_A)) 481 - return PIPE_A; 482 - } 483 - if (hw->disp_a_ctrl & DISPPLANE_PLANE_ENABLE) { 484 - pipe = (hw->disp_a_ctrl >> DISPPLANE_SEL_PIPE_SHIFT); 485 - pipe &= PIPE_MASK; 486 - if (likely(pipe == PIPE_A)) 487 - return PIPE_A; 488 - } 489 - /* Impossible that no pipe is selected - return PIPE_A */ 490 - WARN_ON(pipe == -1); 491 - if (unlikely(pipe == -1)) 492 - pipe = PIPE_A; 493 - 494 - return pipe; 495 - } 496 - 497 - void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, 498 - unsigned red, unsigned green, unsigned blue, 499 - unsigned transp) 500 - { 501 - u32 palette_reg = (dinfo->pipe == PIPE_A) ? 502 - PALETTE_A : PALETTE_B; 503 - 504 - #if VERBOSE > 0 505 - DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n", 506 - regno, red, green, blue); 507 - #endif 508 - 509 - OUTREG(palette_reg + (regno << 2), 510 - (red << PALETTE_8_RED_SHIFT) | 511 - (green << PALETTE_8_GREEN_SHIFT) | 512 - (blue << PALETTE_8_BLUE_SHIFT)); 513 - } 514 - 515 - 516 - int intelfbhw_read_hw_state(struct intelfb_info *dinfo, 517 - struct intelfb_hwstate *hw, int flag) 518 - { 519 - int i; 520 - 521 - #if VERBOSE > 0 522 - DBG_MSG("intelfbhw_read_hw_state\n"); 523 - #endif 524 - 525 - if (!hw || !dinfo) 526 - return -1; 527 - 528 - /* Read in as much of the HW state as possible. */ 529 - hw->vga0_divisor = INREG(VGA0_DIVISOR); 530 - hw->vga1_divisor = INREG(VGA1_DIVISOR); 531 - hw->vga_pd = INREG(VGAPD); 532 - hw->dpll_a = INREG(DPLL_A); 533 - hw->dpll_b = INREG(DPLL_B); 534 - hw->fpa0 = INREG(FPA0); 535 - hw->fpa1 = INREG(FPA1); 536 - hw->fpb0 = INREG(FPB0); 537 - hw->fpb1 = INREG(FPB1); 538 - 539 - if (flag == 1) 540 - return flag; 541 - 542 - #if 0 543 - /* This seems to be a problem with the 852GM/855GM */ 544 - for (i = 0; i < PALETTE_8_ENTRIES; i++) { 545 - hw->palette_a[i] = INREG(PALETTE_A + (i << 2)); 546 - hw->palette_b[i] = INREG(PALETTE_B + (i << 2)); 547 - } 548 - #endif 549 - 550 - if (flag == 2) 551 - return flag; 552 - 553 - hw->htotal_a = INREG(HTOTAL_A); 554 - hw->hblank_a = INREG(HBLANK_A); 555 - hw->hsync_a = INREG(HSYNC_A); 556 - hw->vtotal_a = INREG(VTOTAL_A); 557 - hw->vblank_a = INREG(VBLANK_A); 558 - hw->vsync_a = INREG(VSYNC_A); 559 - hw->src_size_a = INREG(SRC_SIZE_A); 560 - hw->bclrpat_a = INREG(BCLRPAT_A); 561 - hw->htotal_b = INREG(HTOTAL_B); 562 - hw->hblank_b = INREG(HBLANK_B); 563 - hw->hsync_b = INREG(HSYNC_B); 564 - hw->vtotal_b = INREG(VTOTAL_B); 565 - hw->vblank_b = INREG(VBLANK_B); 566 - hw->vsync_b = INREG(VSYNC_B); 567 - hw->src_size_b = INREG(SRC_SIZE_B); 568 - hw->bclrpat_b = INREG(BCLRPAT_B); 569 - 570 - if (flag == 3) 571 - return flag; 572 - 573 - hw->adpa = INREG(ADPA); 574 - hw->dvoa = INREG(DVOA); 575 - hw->dvob = INREG(DVOB); 576 - hw->dvoc = INREG(DVOC); 577 - hw->dvoa_srcdim = INREG(DVOA_SRCDIM); 578 - hw->dvob_srcdim = INREG(DVOB_SRCDIM); 579 - hw->dvoc_srcdim = INREG(DVOC_SRCDIM); 580 - hw->lvds = INREG(LVDS); 581 - 582 - if (flag == 4) 583 - return flag; 584 - 585 - hw->pipe_a_conf = INREG(PIPEACONF); 586 - hw->pipe_b_conf = INREG(PIPEBCONF); 587 - hw->disp_arb = INREG(DISPARB); 588 - 589 - if (flag == 5) 590 - return flag; 591 - 592 - hw->cursor_a_control = INREG(CURSOR_A_CONTROL); 593 - hw->cursor_b_control = INREG(CURSOR_B_CONTROL); 594 - hw->cursor_a_base = INREG(CURSOR_A_BASEADDR); 595 - hw->cursor_b_base = INREG(CURSOR_B_BASEADDR); 596 - 597 - if (flag == 6) 598 - return flag; 599 - 600 - for (i = 0; i < 4; i++) { 601 - hw->cursor_a_palette[i] = INREG(CURSOR_A_PALETTE0 + (i << 2)); 602 - hw->cursor_b_palette[i] = INREG(CURSOR_B_PALETTE0 + (i << 2)); 603 - } 604 - 605 - if (flag == 7) 606 - return flag; 607 - 608 - hw->cursor_size = INREG(CURSOR_SIZE); 609 - 610 - if (flag == 8) 611 - return flag; 612 - 613 - hw->disp_a_ctrl = INREG(DSPACNTR); 614 - hw->disp_b_ctrl = INREG(DSPBCNTR); 615 - hw->disp_a_base = INREG(DSPABASE); 616 - hw->disp_b_base = INREG(DSPBBASE); 617 - hw->disp_a_stride = INREG(DSPASTRIDE); 618 - hw->disp_b_stride = INREG(DSPBSTRIDE); 619 - 620 - if (flag == 9) 621 - return flag; 622 - 623 - hw->vgacntrl = INREG(VGACNTRL); 624 - 625 - if (flag == 10) 626 - return flag; 627 - 628 - hw->add_id = INREG(ADD_ID); 629 - 630 - if (flag == 11) 631 - return flag; 632 - 633 - for (i = 0; i < 7; i++) { 634 - hw->swf0x[i] = INREG(SWF00 + (i << 2)); 635 - hw->swf1x[i] = INREG(SWF10 + (i << 2)); 636 - if (i < 3) 637 - hw->swf3x[i] = INREG(SWF30 + (i << 2)); 638 - } 639 - 640 - for (i = 0; i < 8; i++) 641 - hw->fence[i] = INREG(FENCE + (i << 2)); 642 - 643 - hw->instpm = INREG(INSTPM); 644 - hw->mem_mode = INREG(MEM_MODE); 645 - hw->fw_blc_0 = INREG(FW_BLC_0); 646 - hw->fw_blc_1 = INREG(FW_BLC_1); 647 - 648 - hw->hwstam = INREG16(HWSTAM); 649 - hw->ier = INREG16(IER); 650 - hw->iir = INREG16(IIR); 651 - hw->imr = INREG16(IMR); 652 - 653 - return 0; 654 - } 655 - 656 - 657 - static int calc_vclock3(int index, int m, int n, int p) 658 - { 659 - if (p == 0 || n == 0) 660 - return 0; 661 - return plls[index].ref_clk * m / n / p; 662 - } 663 - 664 - static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, 665 - int lvds) 666 - { 667 - struct pll_min_max *pll = &plls[index]; 668 - u32 m, vco, p; 669 - 670 - m = (5 * (m1 + 2)) + (m2 + 2); 671 - n += 2; 672 - vco = pll->ref_clk * m / n; 673 - 674 - if (index == PLLS_I8xx) 675 - p = ((p1 + 2) * (1 << (p2 + 1))); 676 - else 677 - p = ((p1) * (p2 ? 5 : 10)); 678 - return vco / p; 679 - } 680 - 681 - #if REGDUMP 682 - static void intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, 683 - int *o_p1, int *o_p2) 684 - { 685 - int p1, p2; 686 - 687 - if (IS_I9XX(dinfo)) { 688 - if (dpll & DPLL_P1_FORCE_DIV2) 689 - p1 = 1; 690 - else 691 - p1 = (dpll >> DPLL_P1_SHIFT) & 0xff; 692 - 693 - p1 = ffs(p1); 694 - 695 - p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; 696 - } else { 697 - if (dpll & DPLL_P1_FORCE_DIV2) 698 - p1 = 0; 699 - else 700 - p1 = (dpll >> DPLL_P1_SHIFT) & DPLL_P1_MASK; 701 - p2 = (dpll >> DPLL_P2_SHIFT) & DPLL_P2_MASK; 702 - } 703 - 704 - *o_p1 = p1; 705 - *o_p2 = p2; 706 - } 707 - #endif 708 - 709 - 710 - void intelfbhw_print_hw_state(struct intelfb_info *dinfo, 711 - struct intelfb_hwstate *hw) 712 - { 713 - #if REGDUMP 714 - int i, m1, m2, n, p1, p2; 715 - int index = dinfo->pll_index; 716 - DBG_MSG("intelfbhw_print_hw_state\n"); 717 - 718 - if (!hw) 719 - return; 720 - /* Read in as much of the HW state as possible. */ 721 - printk("hw state dump start\n"); 722 - printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor); 723 - printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor); 724 - printk(" VGAPD: 0x%08x\n", hw->vga_pd); 725 - n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 726 - m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 727 - m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 728 - 729 - intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); 730 - 731 - printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 732 - m1, m2, n, p1, p2); 733 - printk(" VGA0: clock is %d\n", 734 - calc_vclock(index, m1, m2, n, p1, p2, 0)); 735 - 736 - n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 737 - m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 738 - m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 739 - 740 - intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); 741 - printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 742 - m1, m2, n, p1, p2); 743 - printk(" VGA1: clock is %d\n", 744 - calc_vclock(index, m1, m2, n, p1, p2, 0)); 745 - 746 - printk(" DPLL_A: 0x%08x\n", hw->dpll_a); 747 - printk(" DPLL_B: 0x%08x\n", hw->dpll_b); 748 - printk(" FPA0: 0x%08x\n", hw->fpa0); 749 - printk(" FPA1: 0x%08x\n", hw->fpa1); 750 - printk(" FPB0: 0x%08x\n", hw->fpb0); 751 - printk(" FPB1: 0x%08x\n", hw->fpb1); 752 - 753 - n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 754 - m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 755 - m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 756 - 757 - intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2); 758 - 759 - printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 760 - m1, m2, n, p1, p2); 761 - printk(" PLLA0: clock is %d\n", 762 - calc_vclock(index, m1, m2, n, p1, p2, 0)); 763 - 764 - n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 765 - m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 766 - m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 767 - 768 - intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2); 769 - 770 - printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 771 - m1, m2, n, p1, p2); 772 - printk(" PLLA1: clock is %d\n", 773 - calc_vclock(index, m1, m2, n, p1, p2, 0)); 774 - 775 - #if 0 776 - printk(" PALETTE_A:\n"); 777 - for (i = 0; i < PALETTE_8_ENTRIES) 778 - printk(" %3d: 0x%08x\n", i, hw->palette_a[i]); 779 - printk(" PALETTE_B:\n"); 780 - for (i = 0; i < PALETTE_8_ENTRIES) 781 - printk(" %3d: 0x%08x\n", i, hw->palette_b[i]); 782 - #endif 783 - 784 - printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a); 785 - printk(" HBLANK_A: 0x%08x\n", hw->hblank_a); 786 - printk(" HSYNC_A: 0x%08x\n", hw->hsync_a); 787 - printk(" VTOTAL_A: 0x%08x\n", hw->vtotal_a); 788 - printk(" VBLANK_A: 0x%08x\n", hw->vblank_a); 789 - printk(" VSYNC_A: 0x%08x\n", hw->vsync_a); 790 - printk(" SRC_SIZE_A: 0x%08x\n", hw->src_size_a); 791 - printk(" BCLRPAT_A: 0x%08x\n", hw->bclrpat_a); 792 - printk(" HTOTAL_B: 0x%08x\n", hw->htotal_b); 793 - printk(" HBLANK_B: 0x%08x\n", hw->hblank_b); 794 - printk(" HSYNC_B: 0x%08x\n", hw->hsync_b); 795 - printk(" VTOTAL_B: 0x%08x\n", hw->vtotal_b); 796 - printk(" VBLANK_B: 0x%08x\n", hw->vblank_b); 797 - printk(" VSYNC_B: 0x%08x\n", hw->vsync_b); 798 - printk(" SRC_SIZE_B: 0x%08x\n", hw->src_size_b); 799 - printk(" BCLRPAT_B: 0x%08x\n", hw->bclrpat_b); 800 - 801 - printk(" ADPA: 0x%08x\n", hw->adpa); 802 - printk(" DVOA: 0x%08x\n", hw->dvoa); 803 - printk(" DVOB: 0x%08x\n", hw->dvob); 804 - printk(" DVOC: 0x%08x\n", hw->dvoc); 805 - printk(" DVOA_SRCDIM: 0x%08x\n", hw->dvoa_srcdim); 806 - printk(" DVOB_SRCDIM: 0x%08x\n", hw->dvob_srcdim); 807 - printk(" DVOC_SRCDIM: 0x%08x\n", hw->dvoc_srcdim); 808 - printk(" LVDS: 0x%08x\n", hw->lvds); 809 - 810 - printk(" PIPEACONF: 0x%08x\n", hw->pipe_a_conf); 811 - printk(" PIPEBCONF: 0x%08x\n", hw->pipe_b_conf); 812 - printk(" DISPARB: 0x%08x\n", hw->disp_arb); 813 - 814 - printk(" CURSOR_A_CONTROL: 0x%08x\n", hw->cursor_a_control); 815 - printk(" CURSOR_B_CONTROL: 0x%08x\n", hw->cursor_b_control); 816 - printk(" CURSOR_A_BASEADDR: 0x%08x\n", hw->cursor_a_base); 817 - printk(" CURSOR_B_BASEADDR: 0x%08x\n", hw->cursor_b_base); 818 - 819 - printk(" CURSOR_A_PALETTE: "); 820 - for (i = 0; i < 4; i++) { 821 - printk("0x%08x", hw->cursor_a_palette[i]); 822 - if (i < 3) 823 - printk(", "); 824 - } 825 - printk("\n"); 826 - printk(" CURSOR_B_PALETTE: "); 827 - for (i = 0; i < 4; i++) { 828 - printk("0x%08x", hw->cursor_b_palette[i]); 829 - if (i < 3) 830 - printk(", "); 831 - } 832 - printk("\n"); 833 - 834 - printk(" CURSOR_SIZE: 0x%08x\n", hw->cursor_size); 835 - 836 - printk(" DSPACNTR: 0x%08x\n", hw->disp_a_ctrl); 837 - printk(" DSPBCNTR: 0x%08x\n", hw->disp_b_ctrl); 838 - printk(" DSPABASE: 0x%08x\n", hw->disp_a_base); 839 - printk(" DSPBBASE: 0x%08x\n", hw->disp_b_base); 840 - printk(" DSPASTRIDE: 0x%08x\n", hw->disp_a_stride); 841 - printk(" DSPBSTRIDE: 0x%08x\n", hw->disp_b_stride); 842 - 843 - printk(" VGACNTRL: 0x%08x\n", hw->vgacntrl); 844 - printk(" ADD_ID: 0x%08x\n", hw->add_id); 845 - 846 - for (i = 0; i < 7; i++) { 847 - printk(" SWF0%d 0x%08x\n", i, 848 - hw->swf0x[i]); 849 - } 850 - for (i = 0; i < 7; i++) { 851 - printk(" SWF1%d 0x%08x\n", i, 852 - hw->swf1x[i]); 853 - } 854 - for (i = 0; i < 3; i++) { 855 - printk(" SWF3%d 0x%08x\n", i, 856 - hw->swf3x[i]); 857 - } 858 - for (i = 0; i < 8; i++) 859 - printk(" FENCE%d 0x%08x\n", i, 860 - hw->fence[i]); 861 - 862 - printk(" INSTPM 0x%08x\n", hw->instpm); 863 - printk(" MEM_MODE 0x%08x\n", hw->mem_mode); 864 - printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0); 865 - printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1); 866 - 867 - printk(" HWSTAM 0x%04x\n", hw->hwstam); 868 - printk(" IER 0x%04x\n", hw->ier); 869 - printk(" IIR 0x%04x\n", hw->iir); 870 - printk(" IMR 0x%04x\n", hw->imr); 871 - printk("hw state dump end\n"); 872 - #endif 873 - } 874 - 875 - 876 - 877 - /* Split the M parameter into M1 and M2. */ 878 - static int splitm(int index, unsigned int m, unsigned int *retm1, 879 - unsigned int *retm2) 880 - { 881 - int m1, m2; 882 - int testm; 883 - struct pll_min_max *pll = &plls[index]; 884 - 885 - /* no point optimising too much - brute force m */ 886 - for (m1 = pll->min_m1; m1 < pll->max_m1 + 1; m1++) { 887 - for (m2 = pll->min_m2; m2 < pll->max_m2 + 1; m2++) { 888 - testm = (5 * (m1 + 2)) + (m2 + 2); 889 - if (testm == m) { 890 - *retm1 = (unsigned int)m1; 891 - *retm2 = (unsigned int)m2; 892 - return 0; 893 - } 894 - } 895 - } 896 - return 1; 897 - } 898 - 899 - /* Split the P parameter into P1 and P2. */ 900 - static int splitp(int index, unsigned int p, unsigned int *retp1, 901 - unsigned int *retp2) 902 - { 903 - int p1, p2; 904 - struct pll_min_max *pll = &plls[index]; 905 - 906 - if (index == PLLS_I9xx) { 907 - p2 = (p % 10) ? 1 : 0; 908 - 909 - p1 = p / (p2 ? 5 : 10); 910 - 911 - *retp1 = (unsigned int)p1; 912 - *retp2 = (unsigned int)p2; 913 - return 0; 914 - } 915 - 916 - if (p % 4 == 0) 917 - p2 = 1; 918 - else 919 - p2 = 0; 920 - p1 = (p / (1 << (p2 + 1))) - 2; 921 - if (p % 4 == 0 && p1 < pll->min_p1) { 922 - p2 = 0; 923 - p1 = (p / (1 << (p2 + 1))) - 2; 924 - } 925 - if (p1 < pll->min_p1 || p1 > pll->max_p1 || 926 - (p1 + 2) * (1 << (p2 + 1)) != p) { 927 - return 1; 928 - } else { 929 - *retp1 = (unsigned int)p1; 930 - *retp2 = (unsigned int)p2; 931 - return 0; 932 - } 933 - } 934 - 935 - static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, 936 - u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock) 937 - { 938 - u32 m1, m2, n, p1, p2, n1, testm; 939 - u32 f_vco, p, p_best = 0, m, f_out = 0; 940 - u32 err_best = 10000000; 941 - u32 n_best = 0, m_best = 0, f_err; 942 - u32 p_min, p_max, p_inc, div_max; 943 - struct pll_min_max *pll = &plls[index]; 944 - 945 - DBG_MSG("Clock is %d\n", clock); 946 - 947 - div_max = pll->max_vco / clock; 948 - 949 - p_inc = (clock <= pll->p_transition_clk) ? pll->p_inc_lo : pll->p_inc_hi; 950 - p_min = p_inc; 951 - p_max = ROUND_DOWN_TO(div_max, p_inc); 952 - if (p_min < pll->min_p) 953 - p_min = pll->min_p; 954 - if (p_max > pll->max_p) 955 - p_max = pll->max_p; 956 - 957 - DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); 958 - 959 - p = p_min; 960 - do { 961 - if (splitp(index, p, &p1, &p2)) { 962 - WRN_MSG("cannot split p = %d\n", p); 963 - p += p_inc; 964 - continue; 965 - } 966 - n = pll->min_n; 967 - f_vco = clock * p; 968 - 969 - do { 970 - m = ROUND_UP_TO(f_vco * n, pll->ref_clk) / pll->ref_clk; 971 - if (m < pll->min_m) 972 - m = pll->min_m + 1; 973 - if (m > pll->max_m) 974 - m = pll->max_m - 1; 975 - for (testm = m - 1; testm <= m; testm++) { 976 - f_out = calc_vclock3(index, testm, n, p); 977 - if (splitm(index, testm, &m1, &m2)) { 978 - WRN_MSG("cannot split m = %d\n", 979 - testm); 980 - continue; 981 - } 982 - if (clock > f_out) 983 - f_err = clock - f_out; 984 - else/* slightly bias the error for bigger clocks */ 985 - f_err = f_out - clock + 1; 986 - 987 - if (f_err < err_best) { 988 - m_best = testm; 989 - n_best = n; 990 - p_best = p; 991 - err_best = f_err; 992 - } 993 - } 994 - n++; 995 - } while ((n <= pll->max_n) && (f_out >= clock)); 996 - p += p_inc; 997 - } while ((p <= p_max)); 998 - 999 - if (!m_best) { 1000 - WRN_MSG("cannot find parameters for clock %d\n", clock); 1001 - return 1; 1002 - } 1003 - m = m_best; 1004 - n = n_best; 1005 - p = p_best; 1006 - splitm(index, m, &m1, &m2); 1007 - splitp(index, p, &p1, &p2); 1008 - n1 = n - 2; 1009 - 1010 - DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), " 1011 - "f: %d (%d), VCO: %d\n", 1012 - m, m1, m2, n, n1, p, p1, p2, 1013 - calc_vclock3(index, m, n, p), 1014 - calc_vclock(index, m1, m2, n1, p1, p2, 0), 1015 - calc_vclock3(index, m, n, p) * p); 1016 - *retm1 = m1; 1017 - *retm2 = m2; 1018 - *retn = n1; 1019 - *retp1 = p1; 1020 - *retp2 = p2; 1021 - *retclock = calc_vclock(index, m1, m2, n1, p1, p2, 0); 1022 - 1023 - return 0; 1024 - } 1025 - 1026 - static __inline__ int check_overflow(u32 value, u32 limit, 1027 - const char *description) 1028 - { 1029 - if (value > limit) { 1030 - WRN_MSG("%s value %d exceeds limit %d\n", 1031 - description, value, limit); 1032 - return 1; 1033 - } 1034 - return 0; 1035 - } 1036 - 1037 - /* It is assumed that hw is filled in with the initial state information. */ 1038 - int intelfbhw_mode_to_hw(struct intelfb_info *dinfo, 1039 - struct intelfb_hwstate *hw, 1040 - struct fb_var_screeninfo *var) 1041 - { 1042 - int pipe = intelfbhw_active_pipe(hw); 1043 - u32 *dpll, *fp0, *fp1; 1044 - u32 m1, m2, n, p1, p2, clock_target, clock; 1045 - u32 hsync_start, hsync_end, hblank_start, hblank_end, htotal, hactive; 1046 - u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive; 1047 - u32 vsync_pol, hsync_pol; 1048 - u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf; 1049 - u32 stride_alignment; 1050 - 1051 - DBG_MSG("intelfbhw_mode_to_hw\n"); 1052 - 1053 - /* Disable VGA */ 1054 - hw->vgacntrl |= VGA_DISABLE; 1055 - 1056 - /* Set which pipe's registers will be set. */ 1057 - if (pipe == PIPE_B) { 1058 - dpll = &hw->dpll_b; 1059 - fp0 = &hw->fpb0; 1060 - fp1 = &hw->fpb1; 1061 - hs = &hw->hsync_b; 1062 - hb = &hw->hblank_b; 1063 - ht = &hw->htotal_b; 1064 - vs = &hw->vsync_b; 1065 - vb = &hw->vblank_b; 1066 - vt = &hw->vtotal_b; 1067 - ss = &hw->src_size_b; 1068 - pipe_conf = &hw->pipe_b_conf; 1069 - } else { 1070 - dpll = &hw->dpll_a; 1071 - fp0 = &hw->fpa0; 1072 - fp1 = &hw->fpa1; 1073 - hs = &hw->hsync_a; 1074 - hb = &hw->hblank_a; 1075 - ht = &hw->htotal_a; 1076 - vs = &hw->vsync_a; 1077 - vb = &hw->vblank_a; 1078 - vt = &hw->vtotal_a; 1079 - ss = &hw->src_size_a; 1080 - pipe_conf = &hw->pipe_a_conf; 1081 - } 1082 - 1083 - /* Use ADPA register for sync control. */ 1084 - hw->adpa &= ~ADPA_USE_VGA_HVPOLARITY; 1085 - 1086 - /* sync polarity */ 1087 - hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 1088 - ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW; 1089 - vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 1090 - ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW; 1091 - hw->adpa &= ~((ADPA_SYNC_ACTIVE_MASK << ADPA_VSYNC_ACTIVE_SHIFT) | 1092 - (ADPA_SYNC_ACTIVE_MASK << ADPA_HSYNC_ACTIVE_SHIFT)); 1093 - hw->adpa |= (hsync_pol << ADPA_HSYNC_ACTIVE_SHIFT) | 1094 - (vsync_pol << ADPA_VSYNC_ACTIVE_SHIFT); 1095 - 1096 - /* Connect correct pipe to the analog port DAC */ 1097 - hw->adpa &= ~(PIPE_MASK << ADPA_PIPE_SELECT_SHIFT); 1098 - hw->adpa |= (pipe << ADPA_PIPE_SELECT_SHIFT); 1099 - 1100 - /* Set DPMS state to D0 (on) */ 1101 - hw->adpa &= ~ADPA_DPMS_CONTROL_MASK; 1102 - hw->adpa |= ADPA_DPMS_D0; 1103 - 1104 - hw->adpa |= ADPA_DAC_ENABLE; 1105 - 1106 - *dpll |= (DPLL_VCO_ENABLE | DPLL_VGA_MODE_DISABLE); 1107 - *dpll &= ~(DPLL_RATE_SELECT_MASK | DPLL_REFERENCE_SELECT_MASK); 1108 - *dpll |= (DPLL_REFERENCE_DEFAULT | DPLL_RATE_SELECT_FP0); 1109 - 1110 - /* Desired clock in kHz */ 1111 - clock_target = 1000000000 / var->pixclock; 1112 - 1113 - if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2, 1114 - &n, &p1, &p2, &clock)) { 1115 - WRN_MSG("calc_pll_params failed\n"); 1116 - return 1; 1117 - } 1118 - 1119 - /* Check for overflow. */ 1120 - if (check_overflow(p1, DPLL_P1_MASK, "PLL P1 parameter")) 1121 - return 1; 1122 - if (check_overflow(p2, DPLL_P2_MASK, "PLL P2 parameter")) 1123 - return 1; 1124 - if (check_overflow(m1, FP_DIVISOR_MASK, "PLL M1 parameter")) 1125 - return 1; 1126 - if (check_overflow(m2, FP_DIVISOR_MASK, "PLL M2 parameter")) 1127 - return 1; 1128 - if (check_overflow(n, FP_DIVISOR_MASK, "PLL N parameter")) 1129 - return 1; 1130 - 1131 - *dpll &= ~DPLL_P1_FORCE_DIV2; 1132 - *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | 1133 - (DPLL_P1_MASK << DPLL_P1_SHIFT)); 1134 - 1135 - if (IS_I9XX(dinfo)) { 1136 - *dpll |= (p2 << DPLL_I9XX_P2_SHIFT); 1137 - *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT; 1138 - } else 1139 - *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); 1140 - 1141 - *fp0 = (n << FP_N_DIVISOR_SHIFT) | 1142 - (m1 << FP_M1_DIVISOR_SHIFT) | 1143 - (m2 << FP_M2_DIVISOR_SHIFT); 1144 - *fp1 = *fp0; 1145 - 1146 - hw->dvob &= ~PORT_ENABLE; 1147 - hw->dvoc &= ~PORT_ENABLE; 1148 - 1149 - /* Use display plane A. */ 1150 - hw->disp_a_ctrl |= DISPPLANE_PLANE_ENABLE; 1151 - hw->disp_a_ctrl &= ~DISPPLANE_GAMMA_ENABLE; 1152 - hw->disp_a_ctrl &= ~DISPPLANE_PIXFORMAT_MASK; 1153 - switch (intelfb_var_to_depth(var)) { 1154 - case 8: 1155 - hw->disp_a_ctrl |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE; 1156 - break; 1157 - case 15: 1158 - hw->disp_a_ctrl |= DISPPLANE_15_16BPP; 1159 - break; 1160 - case 16: 1161 - hw->disp_a_ctrl |= DISPPLANE_16BPP; 1162 - break; 1163 - case 24: 1164 - hw->disp_a_ctrl |= DISPPLANE_32BPP_NO_ALPHA; 1165 - break; 1166 - } 1167 - hw->disp_a_ctrl &= ~(PIPE_MASK << DISPPLANE_SEL_PIPE_SHIFT); 1168 - hw->disp_a_ctrl |= (pipe << DISPPLANE_SEL_PIPE_SHIFT); 1169 - 1170 - /* Set CRTC registers. */ 1171 - hactive = var->xres; 1172 - hsync_start = hactive + var->right_margin; 1173 - hsync_end = hsync_start + var->hsync_len; 1174 - htotal = hsync_end + var->left_margin; 1175 - hblank_start = hactive; 1176 - hblank_end = htotal; 1177 - 1178 - DBG_MSG("H: act %d, ss %d, se %d, tot %d bs %d, be %d\n", 1179 - hactive, hsync_start, hsync_end, htotal, hblank_start, 1180 - hblank_end); 1181 - 1182 - vactive = var->yres; 1183 - if (var->vmode & FB_VMODE_INTERLACED) 1184 - vactive--; /* the chip adds 2 halflines automatically */ 1185 - vsync_start = vactive + var->lower_margin; 1186 - vsync_end = vsync_start + var->vsync_len; 1187 - vtotal = vsync_end + var->upper_margin; 1188 - vblank_start = vactive; 1189 - vblank_end = vsync_end + 1; 1190 - 1191 - DBG_MSG("V: act %d, ss %d, se %d, tot %d bs %d, be %d\n", 1192 - vactive, vsync_start, vsync_end, vtotal, vblank_start, 1193 - vblank_end); 1194 - 1195 - /* Adjust for register values, and check for overflow. */ 1196 - hactive--; 1197 - if (check_overflow(hactive, HACTIVE_MASK, "CRTC hactive")) 1198 - return 1; 1199 - hsync_start--; 1200 - if (check_overflow(hsync_start, HSYNCSTART_MASK, "CRTC hsync_start")) 1201 - return 1; 1202 - hsync_end--; 1203 - if (check_overflow(hsync_end, HSYNCEND_MASK, "CRTC hsync_end")) 1204 - return 1; 1205 - htotal--; 1206 - if (check_overflow(htotal, HTOTAL_MASK, "CRTC htotal")) 1207 - return 1; 1208 - hblank_start--; 1209 - if (check_overflow(hblank_start, HBLANKSTART_MASK, "CRTC hblank_start")) 1210 - return 1; 1211 - hblank_end--; 1212 - if (check_overflow(hblank_end, HBLANKEND_MASK, "CRTC hblank_end")) 1213 - return 1; 1214 - 1215 - vactive--; 1216 - if (check_overflow(vactive, VACTIVE_MASK, "CRTC vactive")) 1217 - return 1; 1218 - vsync_start--; 1219 - if (check_overflow(vsync_start, VSYNCSTART_MASK, "CRTC vsync_start")) 1220 - return 1; 1221 - vsync_end--; 1222 - if (check_overflow(vsync_end, VSYNCEND_MASK, "CRTC vsync_end")) 1223 - return 1; 1224 - vtotal--; 1225 - if (check_overflow(vtotal, VTOTAL_MASK, "CRTC vtotal")) 1226 - return 1; 1227 - vblank_start--; 1228 - if (check_overflow(vblank_start, VBLANKSTART_MASK, "CRTC vblank_start")) 1229 - return 1; 1230 - vblank_end--; 1231 - if (check_overflow(vblank_end, VBLANKEND_MASK, "CRTC vblank_end")) 1232 - return 1; 1233 - 1234 - *ht = (htotal << HTOTAL_SHIFT) | (hactive << HACTIVE_SHIFT); 1235 - *hb = (hblank_start << HBLANKSTART_SHIFT) | 1236 - (hblank_end << HSYNCEND_SHIFT); 1237 - *hs = (hsync_start << HSYNCSTART_SHIFT) | (hsync_end << HSYNCEND_SHIFT); 1238 - 1239 - *vt = (vtotal << VTOTAL_SHIFT) | (vactive << VACTIVE_SHIFT); 1240 - *vb = (vblank_start << VBLANKSTART_SHIFT) | 1241 - (vblank_end << VSYNCEND_SHIFT); 1242 - *vs = (vsync_start << VSYNCSTART_SHIFT) | (vsync_end << VSYNCEND_SHIFT); 1243 - *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) | 1244 - (vactive << SRC_SIZE_VERT_SHIFT); 1245 - 1246 - hw->disp_a_stride = dinfo->pitch; 1247 - DBG_MSG("pitch is %d\n", hw->disp_a_stride); 1248 - 1249 - hw->disp_a_base = hw->disp_a_stride * var->yoffset + 1250 - var->xoffset * var->bits_per_pixel / 8; 1251 - 1252 - hw->disp_a_base += dinfo->fb.offset << 12; 1253 - 1254 - /* Check stride alignment. */ 1255 - stride_alignment = IS_I9XX(dinfo) ? STRIDE_ALIGNMENT_I9XX : 1256 - STRIDE_ALIGNMENT; 1257 - if (hw->disp_a_stride % stride_alignment != 0) { 1258 - WRN_MSG("display stride %d has bad alignment %d\n", 1259 - hw->disp_a_stride, stride_alignment); 1260 - return 1; 1261 - } 1262 - 1263 - /* Set the palette to 8-bit mode. */ 1264 - *pipe_conf &= ~PIPECONF_GAMMA; 1265 - 1266 - if (var->vmode & FB_VMODE_INTERLACED) 1267 - *pipe_conf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; 1268 - else 1269 - *pipe_conf &= ~PIPECONF_INTERLACE_MASK; 1270 - 1271 - return 0; 1272 - } 1273 - 1274 - /* Program a (non-VGA) video mode. */ 1275 - int intelfbhw_program_mode(struct intelfb_info *dinfo, 1276 - const struct intelfb_hwstate *hw, int blank) 1277 - { 1278 - u32 tmp; 1279 - const u32 *dpll, *fp0, *fp1, *pipe_conf; 1280 - const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss; 1281 - u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg, pipe_stat_reg; 1282 - u32 hsync_reg, htotal_reg, hblank_reg; 1283 - u32 vsync_reg, vtotal_reg, vblank_reg; 1284 - u32 src_size_reg; 1285 - u32 count, tmp_val[3]; 1286 - 1287 - /* Assume single pipe */ 1288 - 1289 - #if VERBOSE > 0 1290 - DBG_MSG("intelfbhw_program_mode\n"); 1291 - #endif 1292 - 1293 - /* Disable VGA */ 1294 - tmp = INREG(VGACNTRL); 1295 - tmp |= VGA_DISABLE; 1296 - OUTREG(VGACNTRL, tmp); 1297 - 1298 - dinfo->pipe = intelfbhw_active_pipe(hw); 1299 - 1300 - if (dinfo->pipe == PIPE_B) { 1301 - dpll = &hw->dpll_b; 1302 - fp0 = &hw->fpb0; 1303 - fp1 = &hw->fpb1; 1304 - pipe_conf = &hw->pipe_b_conf; 1305 - hs = &hw->hsync_b; 1306 - hb = &hw->hblank_b; 1307 - ht = &hw->htotal_b; 1308 - vs = &hw->vsync_b; 1309 - vb = &hw->vblank_b; 1310 - vt = &hw->vtotal_b; 1311 - ss = &hw->src_size_b; 1312 - dpll_reg = DPLL_B; 1313 - fp0_reg = FPB0; 1314 - fp1_reg = FPB1; 1315 - pipe_conf_reg = PIPEBCONF; 1316 - pipe_stat_reg = PIPEBSTAT; 1317 - hsync_reg = HSYNC_B; 1318 - htotal_reg = HTOTAL_B; 1319 - hblank_reg = HBLANK_B; 1320 - vsync_reg = VSYNC_B; 1321 - vtotal_reg = VTOTAL_B; 1322 - vblank_reg = VBLANK_B; 1323 - src_size_reg = SRC_SIZE_B; 1324 - } else { 1325 - dpll = &hw->dpll_a; 1326 - fp0 = &hw->fpa0; 1327 - fp1 = &hw->fpa1; 1328 - pipe_conf = &hw->pipe_a_conf; 1329 - hs = &hw->hsync_a; 1330 - hb = &hw->hblank_a; 1331 - ht = &hw->htotal_a; 1332 - vs = &hw->vsync_a; 1333 - vb = &hw->vblank_a; 1334 - vt = &hw->vtotal_a; 1335 - ss = &hw->src_size_a; 1336 - dpll_reg = DPLL_A; 1337 - fp0_reg = FPA0; 1338 - fp1_reg = FPA1; 1339 - pipe_conf_reg = PIPEACONF; 1340 - pipe_stat_reg = PIPEASTAT; 1341 - hsync_reg = HSYNC_A; 1342 - htotal_reg = HTOTAL_A; 1343 - hblank_reg = HBLANK_A; 1344 - vsync_reg = VSYNC_A; 1345 - vtotal_reg = VTOTAL_A; 1346 - vblank_reg = VBLANK_A; 1347 - src_size_reg = SRC_SIZE_A; 1348 - } 1349 - 1350 - /* turn off pipe */ 1351 - tmp = INREG(pipe_conf_reg); 1352 - tmp &= ~PIPECONF_ENABLE; 1353 - OUTREG(pipe_conf_reg, tmp); 1354 - 1355 - count = 0; 1356 - do { 1357 - tmp_val[count % 3] = INREG(PIPEA_DSL); 1358 - if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1] == tmp_val[2])) 1359 - break; 1360 - count++; 1361 - udelay(1); 1362 - if (count % 200 == 0) { 1363 - tmp = INREG(pipe_conf_reg); 1364 - tmp &= ~PIPECONF_ENABLE; 1365 - OUTREG(pipe_conf_reg, tmp); 1366 - } 1367 - } while (count < 2000); 1368 - 1369 - OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); 1370 - 1371 - /* Disable planes A and B. */ 1372 - tmp = INREG(DSPACNTR); 1373 - tmp &= ~DISPPLANE_PLANE_ENABLE; 1374 - OUTREG(DSPACNTR, tmp); 1375 - tmp = INREG(DSPBCNTR); 1376 - tmp &= ~DISPPLANE_PLANE_ENABLE; 1377 - OUTREG(DSPBCNTR, tmp); 1378 - 1379 - /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ 1380 - mdelay(20); 1381 - 1382 - OUTREG(DVOB, INREG(DVOB) & ~PORT_ENABLE); 1383 - OUTREG(DVOC, INREG(DVOC) & ~PORT_ENABLE); 1384 - OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); 1385 - 1386 - /* Disable Sync */ 1387 - tmp = INREG(ADPA); 1388 - tmp &= ~ADPA_DPMS_CONTROL_MASK; 1389 - tmp |= ADPA_DPMS_D3; 1390 - OUTREG(ADPA, tmp); 1391 - 1392 - /* do some funky magic - xyzzy */ 1393 - OUTREG(0x61204, 0xabcd0000); 1394 - 1395 - /* turn off PLL */ 1396 - tmp = INREG(dpll_reg); 1397 - tmp &= ~DPLL_VCO_ENABLE; 1398 - OUTREG(dpll_reg, tmp); 1399 - 1400 - /* Set PLL parameters */ 1401 - OUTREG(fp0_reg, *fp0); 1402 - OUTREG(fp1_reg, *fp1); 1403 - 1404 - /* Enable PLL */ 1405 - OUTREG(dpll_reg, *dpll); 1406 - 1407 - /* Set DVOs B/C */ 1408 - OUTREG(DVOB, hw->dvob); 1409 - OUTREG(DVOC, hw->dvoc); 1410 - 1411 - /* undo funky magic */ 1412 - OUTREG(0x61204, 0x00000000); 1413 - 1414 - /* Set ADPA */ 1415 - OUTREG(ADPA, INREG(ADPA) | ADPA_DAC_ENABLE); 1416 - OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3); 1417 - 1418 - /* Set pipe parameters */ 1419 - OUTREG(hsync_reg, *hs); 1420 - OUTREG(hblank_reg, *hb); 1421 - OUTREG(htotal_reg, *ht); 1422 - OUTREG(vsync_reg, *vs); 1423 - OUTREG(vblank_reg, *vb); 1424 - OUTREG(vtotal_reg, *vt); 1425 - OUTREG(src_size_reg, *ss); 1426 - 1427 - switch (dinfo->info->var.vmode & (FB_VMODE_INTERLACED | 1428 - FB_VMODE_ODD_FLD_FIRST)) { 1429 - case FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST: 1430 - OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_ODD_EN); 1431 - break; 1432 - case FB_VMODE_INTERLACED: /* even lines first */ 1433 - OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_EVEN_EN); 1434 - break; 1435 - default: /* non-interlaced */ 1436 - OUTREG(pipe_stat_reg, 0xFFFF); /* clear all status bits only */ 1437 - } 1438 - /* Enable pipe */ 1439 - OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); 1440 - 1441 - /* Enable sync */ 1442 - tmp = INREG(ADPA); 1443 - tmp &= ~ADPA_DPMS_CONTROL_MASK; 1444 - tmp |= ADPA_DPMS_D0; 1445 - OUTREG(ADPA, tmp); 1446 - 1447 - /* setup display plane */ 1448 - if (dinfo->pdev->device == PCI_DEVICE_ID_INTEL_830M) { 1449 - /* 1450 - * i830M errata: the display plane must be enabled 1451 - * to allow writes to the other bits in the plane 1452 - * control register. 1453 - */ 1454 - tmp = INREG(DSPACNTR); 1455 - if ((tmp & DISPPLANE_PLANE_ENABLE) != DISPPLANE_PLANE_ENABLE) { 1456 - tmp |= DISPPLANE_PLANE_ENABLE; 1457 - OUTREG(DSPACNTR, tmp); 1458 - OUTREG(DSPACNTR, 1459 - hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); 1460 - mdelay(1); 1461 - } 1462 - } 1463 - 1464 - OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); 1465 - OUTREG(DSPASTRIDE, hw->disp_a_stride); 1466 - OUTREG(DSPABASE, hw->disp_a_base); 1467 - 1468 - /* Enable plane */ 1469 - if (!blank) { 1470 - tmp = INREG(DSPACNTR); 1471 - tmp |= DISPPLANE_PLANE_ENABLE; 1472 - OUTREG(DSPACNTR, tmp); 1473 - OUTREG(DSPABASE, hw->disp_a_base); 1474 - } 1475 - 1476 - return 0; 1477 - } 1478 - 1479 - /* forward declarations */ 1480 - static void refresh_ring(struct intelfb_info *dinfo); 1481 - static void reset_state(struct intelfb_info *dinfo); 1482 - static void do_flush(struct intelfb_info *dinfo); 1483 - 1484 - static u32 get_ring_space(struct intelfb_info *dinfo) 1485 - { 1486 - u32 ring_space; 1487 - 1488 - if (dinfo->ring_tail >= dinfo->ring_head) 1489 - ring_space = dinfo->ring.size - 1490 - (dinfo->ring_tail - dinfo->ring_head); 1491 - else 1492 - ring_space = dinfo->ring_head - dinfo->ring_tail; 1493 - 1494 - if (ring_space > RING_MIN_FREE) 1495 - ring_space -= RING_MIN_FREE; 1496 - else 1497 - ring_space = 0; 1498 - 1499 - return ring_space; 1500 - } 1501 - 1502 - static int wait_ring(struct intelfb_info *dinfo, int n) 1503 - { 1504 - int i = 0; 1505 - unsigned long end; 1506 - u32 last_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1507 - 1508 - #if VERBOSE > 0 1509 - DBG_MSG("wait_ring: %d\n", n); 1510 - #endif 1511 - 1512 - end = jiffies + (HZ * 3); 1513 - while (dinfo->ring_space < n) { 1514 - dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1515 - dinfo->ring_space = get_ring_space(dinfo); 1516 - 1517 - if (dinfo->ring_head != last_head) { 1518 - end = jiffies + (HZ * 3); 1519 - last_head = dinfo->ring_head; 1520 - } 1521 - i++; 1522 - if (time_before(end, jiffies)) { 1523 - if (!i) { 1524 - /* Try again */ 1525 - reset_state(dinfo); 1526 - refresh_ring(dinfo); 1527 - do_flush(dinfo); 1528 - end = jiffies + (HZ * 3); 1529 - i = 1; 1530 - } else { 1531 - WRN_MSG("ring buffer : space: %d wanted %d\n", 1532 - dinfo->ring_space, n); 1533 - WRN_MSG("lockup - turning off hardware " 1534 - "acceleration\n"); 1535 - dinfo->ring_lockup = 1; 1536 - break; 1537 - } 1538 - } 1539 - udelay(1); 1540 - } 1541 - return i; 1542 - } 1543 - 1544 - static void do_flush(struct intelfb_info *dinfo) 1545 - { 1546 - START_RING(2); 1547 - OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); 1548 - OUT_RING(MI_NOOP); 1549 - ADVANCE_RING(); 1550 - } 1551 - 1552 - void intelfbhw_do_sync(struct intelfb_info *dinfo) 1553 - { 1554 - #if VERBOSE > 0 1555 - DBG_MSG("intelfbhw_do_sync\n"); 1556 - #endif 1557 - 1558 - if (!dinfo->accel) 1559 - return; 1560 - 1561 - /* 1562 - * Send a flush, then wait until the ring is empty. This is what 1563 - * the XFree86 driver does, and actually it doesn't seem a lot worse 1564 - * than the recommended method (both have problems). 1565 - */ 1566 - do_flush(dinfo); 1567 - wait_ring(dinfo, dinfo->ring.size - RING_MIN_FREE); 1568 - dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE; 1569 - } 1570 - 1571 - static void refresh_ring(struct intelfb_info *dinfo) 1572 - { 1573 - #if VERBOSE > 0 1574 - DBG_MSG("refresh_ring\n"); 1575 - #endif 1576 - 1577 - dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1578 - dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; 1579 - dinfo->ring_space = get_ring_space(dinfo); 1580 - } 1581 - 1582 - static void reset_state(struct intelfb_info *dinfo) 1583 - { 1584 - int i; 1585 - u32 tmp; 1586 - 1587 - #if VERBOSE > 0 1588 - DBG_MSG("reset_state\n"); 1589 - #endif 1590 - 1591 - for (i = 0; i < FENCE_NUM; i++) 1592 - OUTREG(FENCE + (i << 2), 0); 1593 - 1594 - /* Flush the ring buffer if it's enabled. */ 1595 - tmp = INREG(PRI_RING_LENGTH); 1596 - if (tmp & RING_ENABLE) { 1597 - #if VERBOSE > 0 1598 - DBG_MSG("reset_state: ring was enabled\n"); 1599 - #endif 1600 - refresh_ring(dinfo); 1601 - intelfbhw_do_sync(dinfo); 1602 - DO_RING_IDLE(); 1603 - } 1604 - 1605 - OUTREG(PRI_RING_LENGTH, 0); 1606 - OUTREG(PRI_RING_HEAD, 0); 1607 - OUTREG(PRI_RING_TAIL, 0); 1608 - OUTREG(PRI_RING_START, 0); 1609 - } 1610 - 1611 - /* Stop the 2D engine, and turn off the ring buffer. */ 1612 - void intelfbhw_2d_stop(struct intelfb_info *dinfo) 1613 - { 1614 - #if VERBOSE > 0 1615 - DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", 1616 - dinfo->accel, dinfo->ring_active); 1617 - #endif 1618 - 1619 - if (!dinfo->accel) 1620 - return; 1621 - 1622 - dinfo->ring_active = 0; 1623 - reset_state(dinfo); 1624 - } 1625 - 1626 - /* 1627 - * Enable the ring buffer, and initialise the 2D engine. 1628 - * It is assumed that the graphics engine has been stopped by previously 1629 - * calling intelfb_2d_stop(). 1630 - */ 1631 - void intelfbhw_2d_start(struct intelfb_info *dinfo) 1632 - { 1633 - #if VERBOSE > 0 1634 - DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n", 1635 - dinfo->accel, dinfo->ring_active); 1636 - #endif 1637 - 1638 - if (!dinfo->accel) 1639 - return; 1640 - 1641 - /* Initialise the primary ring buffer. */ 1642 - OUTREG(PRI_RING_LENGTH, 0); 1643 - OUTREG(PRI_RING_TAIL, 0); 1644 - OUTREG(PRI_RING_HEAD, 0); 1645 - 1646 - OUTREG(PRI_RING_START, dinfo->ring.physical & RING_START_MASK); 1647 - OUTREG(PRI_RING_LENGTH, 1648 - ((dinfo->ring.size - GTT_PAGE_SIZE) & RING_LENGTH_MASK) | 1649 - RING_NO_REPORT | RING_ENABLE); 1650 - refresh_ring(dinfo); 1651 - dinfo->ring_active = 1; 1652 - } 1653 - 1654 - /* 2D fillrect (solid fill or invert) */ 1655 - void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, 1656 - u32 h, u32 color, u32 pitch, u32 bpp, u32 rop) 1657 - { 1658 - u32 br00, br09, br13, br14, br16; 1659 - 1660 - #if VERBOSE > 0 1661 - DBG_MSG("intelfbhw_do_fillrect: (%d,%d) %dx%d, c 0x%06x, p %d bpp %d, " 1662 - "rop 0x%02x\n", x, y, w, h, color, pitch, bpp, rop); 1663 - #endif 1664 - 1665 - br00 = COLOR_BLT_CMD; 1666 - br09 = dinfo->fb_start + (y * pitch + x * (bpp / 8)); 1667 - br13 = (rop << ROP_SHIFT) | pitch; 1668 - br14 = (h << HEIGHT_SHIFT) | ((w * (bpp / 8)) << WIDTH_SHIFT); 1669 - br16 = color; 1670 - 1671 - switch (bpp) { 1672 - case 8: 1673 - br13 |= COLOR_DEPTH_8; 1674 - break; 1675 - case 16: 1676 - br13 |= COLOR_DEPTH_16; 1677 - break; 1678 - case 32: 1679 - br13 |= COLOR_DEPTH_32; 1680 - br00 |= WRITE_ALPHA | WRITE_RGB; 1681 - break; 1682 - } 1683 - 1684 - START_RING(6); 1685 - OUT_RING(br00); 1686 - OUT_RING(br13); 1687 - OUT_RING(br14); 1688 - OUT_RING(br09); 1689 - OUT_RING(br16); 1690 - OUT_RING(MI_NOOP); 1691 - ADVANCE_RING(); 1692 - 1693 - #if VERBOSE > 0 1694 - DBG_MSG("ring = 0x%08x, 0x%08x (%d)\n", dinfo->ring_head, 1695 - dinfo->ring_tail, dinfo->ring_space); 1696 - #endif 1697 - } 1698 - 1699 - void 1700 - intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury, 1701 - u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch, u32 bpp) 1702 - { 1703 - u32 br00, br09, br11, br12, br13, br22, br23, br26; 1704 - 1705 - #if VERBOSE > 0 1706 - DBG_MSG("intelfbhw_do_bitblt: (%d,%d)->(%d,%d) %dx%d, p %d bpp %d\n", 1707 - curx, cury, dstx, dsty, w, h, pitch, bpp); 1708 - #endif 1709 - 1710 - br00 = XY_SRC_COPY_BLT_CMD; 1711 - br09 = dinfo->fb_start; 1712 - br11 = (pitch << PITCH_SHIFT); 1713 - br12 = dinfo->fb_start; 1714 - br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT); 1715 - br22 = (dstx << WIDTH_SHIFT) | (dsty << HEIGHT_SHIFT); 1716 - br23 = ((dstx + w) << WIDTH_SHIFT) | 1717 - ((dsty + h) << HEIGHT_SHIFT); 1718 - br26 = (curx << WIDTH_SHIFT) | (cury << HEIGHT_SHIFT); 1719 - 1720 - switch (bpp) { 1721 - case 8: 1722 - br13 |= COLOR_DEPTH_8; 1723 - break; 1724 - case 16: 1725 - br13 |= COLOR_DEPTH_16; 1726 - break; 1727 - case 32: 1728 - br13 |= COLOR_DEPTH_32; 1729 - br00 |= WRITE_ALPHA | WRITE_RGB; 1730 - break; 1731 - } 1732 - 1733 - START_RING(8); 1734 - OUT_RING(br00); 1735 - OUT_RING(br13); 1736 - OUT_RING(br22); 1737 - OUT_RING(br23); 1738 - OUT_RING(br09); 1739 - OUT_RING(br26); 1740 - OUT_RING(br11); 1741 - OUT_RING(br12); 1742 - ADVANCE_RING(); 1743 - } 1744 - 1745 - int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w, 1746 - u32 h, const u8* cdat, u32 x, u32 y, u32 pitch, 1747 - u32 bpp) 1748 - { 1749 - int nbytes, ndwords, pad, tmp; 1750 - u32 br00, br09, br13, br18, br19, br22, br23; 1751 - int dat, ix, iy, iw; 1752 - int i, j; 1753 - 1754 - #if VERBOSE > 0 1755 - DBG_MSG("intelfbhw_do_drawglyph: (%d,%d) %dx%d\n", x, y, w, h); 1756 - #endif 1757 - 1758 - /* size in bytes of a padded scanline */ 1759 - nbytes = ROUND_UP_TO(w, 16) / 8; 1760 - 1761 - /* Total bytes of padded scanline data to write out. */ 1762 - nbytes = nbytes * h; 1763 - 1764 - /* 1765 - * Check if the glyph data exceeds the immediate mode limit. 1766 - * It would take a large font (1K pixels) to hit this limit. 1767 - */ 1768 - if (nbytes > MAX_MONO_IMM_SIZE) 1769 - return 0; 1770 - 1771 - /* Src data is packaged a dword (32-bit) at a time. */ 1772 - ndwords = ROUND_UP_TO(nbytes, 4) / 4; 1773 - 1774 - /* 1775 - * Ring has to be padded to a quad word. But because the command starts 1776 - with 7 bytes, pad only if there is an even number of ndwords 1777 - */ 1778 - pad = !(ndwords % 2); 1779 - 1780 - tmp = (XY_MONO_SRC_IMM_BLT_CMD & DW_LENGTH_MASK) + ndwords; 1781 - br00 = (XY_MONO_SRC_IMM_BLT_CMD & ~DW_LENGTH_MASK) | tmp; 1782 - br09 = dinfo->fb_start; 1783 - br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT); 1784 - br18 = bg; 1785 - br19 = fg; 1786 - br22 = (x << WIDTH_SHIFT) | (y << HEIGHT_SHIFT); 1787 - br23 = ((x + w) << WIDTH_SHIFT) | ((y + h) << HEIGHT_SHIFT); 1788 - 1789 - switch (bpp) { 1790 - case 8: 1791 - br13 |= COLOR_DEPTH_8; 1792 - break; 1793 - case 16: 1794 - br13 |= COLOR_DEPTH_16; 1795 - break; 1796 - case 32: 1797 - br13 |= COLOR_DEPTH_32; 1798 - br00 |= WRITE_ALPHA | WRITE_RGB; 1799 - break; 1800 - } 1801 - 1802 - START_RING(8 + ndwords); 1803 - OUT_RING(br00); 1804 - OUT_RING(br13); 1805 - OUT_RING(br22); 1806 - OUT_RING(br23); 1807 - OUT_RING(br09); 1808 - OUT_RING(br18); 1809 - OUT_RING(br19); 1810 - ix = iy = 0; 1811 - iw = ROUND_UP_TO(w, 8) / 8; 1812 - while (ndwords--) { 1813 - dat = 0; 1814 - for (j = 0; j < 2; ++j) { 1815 - for (i = 0; i < 2; ++i) { 1816 - if (ix != iw || i == 0) 1817 - dat |= cdat[iy*iw + ix++] << (i+j*2)*8; 1818 - } 1819 - if (ix == iw && iy != (h-1)) { 1820 - ix = 0; 1821 - ++iy; 1822 - } 1823 - } 1824 - OUT_RING(dat); 1825 - } 1826 - if (pad) 1827 - OUT_RING(MI_NOOP); 1828 - ADVANCE_RING(); 1829 - 1830 - return 1; 1831 - } 1832 - 1833 - /* HW cursor functions. */ 1834 - void intelfbhw_cursor_init(struct intelfb_info *dinfo) 1835 - { 1836 - u32 tmp; 1837 - 1838 - #if VERBOSE > 0 1839 - DBG_MSG("intelfbhw_cursor_init\n"); 1840 - #endif 1841 - 1842 - if (dinfo->mobile || IS_I9XX(dinfo)) { 1843 - if (!dinfo->cursor.physical) 1844 - return; 1845 - tmp = INREG(CURSOR_A_CONTROL); 1846 - tmp &= ~(CURSOR_MODE_MASK | CURSOR_MOBILE_GAMMA_ENABLE | 1847 - CURSOR_MEM_TYPE_LOCAL | 1848 - (1 << CURSOR_PIPE_SELECT_SHIFT)); 1849 - tmp |= CURSOR_MODE_DISABLE; 1850 - OUTREG(CURSOR_A_CONTROL, tmp); 1851 - OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1852 - } else { 1853 - tmp = INREG(CURSOR_CONTROL); 1854 - tmp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE | 1855 - CURSOR_ENABLE | CURSOR_STRIDE_MASK); 1856 - tmp |= CURSOR_FORMAT_3C; 1857 - OUTREG(CURSOR_CONTROL, tmp); 1858 - OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.offset << 12); 1859 - tmp = (64 << CURSOR_SIZE_H_SHIFT) | 1860 - (64 << CURSOR_SIZE_V_SHIFT); 1861 - OUTREG(CURSOR_SIZE, tmp); 1862 - } 1863 - } 1864 - 1865 - void intelfbhw_cursor_hide(struct intelfb_info *dinfo) 1866 - { 1867 - u32 tmp; 1868 - 1869 - #if VERBOSE > 0 1870 - DBG_MSG("intelfbhw_cursor_hide\n"); 1871 - #endif 1872 - 1873 - dinfo->cursor_on = 0; 1874 - if (dinfo->mobile || IS_I9XX(dinfo)) { 1875 - if (!dinfo->cursor.physical) 1876 - return; 1877 - tmp = INREG(CURSOR_A_CONTROL); 1878 - tmp &= ~CURSOR_MODE_MASK; 1879 - tmp |= CURSOR_MODE_DISABLE; 1880 - OUTREG(CURSOR_A_CONTROL, tmp); 1881 - /* Flush changes */ 1882 - OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1883 - } else { 1884 - tmp = INREG(CURSOR_CONTROL); 1885 - tmp &= ~CURSOR_ENABLE; 1886 - OUTREG(CURSOR_CONTROL, tmp); 1887 - } 1888 - } 1889 - 1890 - void intelfbhw_cursor_show(struct intelfb_info *dinfo) 1891 - { 1892 - u32 tmp; 1893 - 1894 - #if VERBOSE > 0 1895 - DBG_MSG("intelfbhw_cursor_show\n"); 1896 - #endif 1897 - 1898 - dinfo->cursor_on = 1; 1899 - 1900 - if (dinfo->cursor_blanked) 1901 - return; 1902 - 1903 - if (dinfo->mobile || IS_I9XX(dinfo)) { 1904 - if (!dinfo->cursor.physical) 1905 - return; 1906 - tmp = INREG(CURSOR_A_CONTROL); 1907 - tmp &= ~CURSOR_MODE_MASK; 1908 - tmp |= CURSOR_MODE_64_4C_AX; 1909 - OUTREG(CURSOR_A_CONTROL, tmp); 1910 - /* Flush changes */ 1911 - OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1912 - } else { 1913 - tmp = INREG(CURSOR_CONTROL); 1914 - tmp |= CURSOR_ENABLE; 1915 - OUTREG(CURSOR_CONTROL, tmp); 1916 - } 1917 - } 1918 - 1919 - void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y) 1920 - { 1921 - u32 tmp; 1922 - 1923 - #if VERBOSE > 0 1924 - DBG_MSG("intelfbhw_cursor_setpos: (%d, %d)\n", x, y); 1925 - #endif 1926 - 1927 - /* 1928 - * Sets the position. The coordinates are assumed to already 1929 - * have any offset adjusted. Assume that the cursor is never 1930 - * completely off-screen, and that x, y are always >= 0. 1931 - */ 1932 - 1933 - tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | 1934 - ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); 1935 - OUTREG(CURSOR_A_POSITION, tmp); 1936 - 1937 - if (IS_I9XX(dinfo)) 1938 - OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1939 - } 1940 - 1941 - void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg) 1942 - { 1943 - #if VERBOSE > 0 1944 - DBG_MSG("intelfbhw_cursor_setcolor\n"); 1945 - #endif 1946 - 1947 - OUTREG(CURSOR_A_PALETTE0, bg & CURSOR_PALETTE_MASK); 1948 - OUTREG(CURSOR_A_PALETTE1, fg & CURSOR_PALETTE_MASK); 1949 - OUTREG(CURSOR_A_PALETTE2, fg & CURSOR_PALETTE_MASK); 1950 - OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK); 1951 - } 1952 - 1953 - void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height, 1954 - u8 *data) 1955 - { 1956 - u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1957 - int i, j, w = width / 8; 1958 - int mod = width % 8, t_mask, d_mask; 1959 - 1960 - #if VERBOSE > 0 1961 - DBG_MSG("intelfbhw_cursor_load\n"); 1962 - #endif 1963 - 1964 - if (!dinfo->cursor.virtual) 1965 - return; 1966 - 1967 - t_mask = 0xff >> mod; 1968 - d_mask = ~(0xff >> mod); 1969 - for (i = height; i--; ) { 1970 - for (j = 0; j < w; j++) { 1971 - writeb(0x00, addr + j); 1972 - writeb(*(data++), addr + j+8); 1973 - } 1974 - if (mod) { 1975 - writeb(t_mask, addr + j); 1976 - writeb(*(data++) & d_mask, addr + j+8); 1977 - } 1978 - addr += 16; 1979 - } 1980 - } 1981 - 1982 - void intelfbhw_cursor_reset(struct intelfb_info *dinfo) 1983 - { 1984 - u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1985 - int i, j; 1986 - 1987 - #if VERBOSE > 0 1988 - DBG_MSG("intelfbhw_cursor_reset\n"); 1989 - #endif 1990 - 1991 - if (!dinfo->cursor.virtual) 1992 - return; 1993 - 1994 - for (i = 64; i--; ) { 1995 - for (j = 0; j < 8; j++) { 1996 - writeb(0xff, addr + j+0); 1997 - writeb(0x00, addr + j+8); 1998 - } 1999 - addr += 16; 2000 - } 2001 - } 2002 - 2003 - static irqreturn_t intelfbhw_irq(int irq, void *dev_id) 2004 - { 2005 - u16 tmp; 2006 - struct intelfb_info *dinfo = dev_id; 2007 - 2008 - spin_lock(&dinfo->int_lock); 2009 - 2010 - tmp = INREG16(IIR); 2011 - if (dinfo->info->var.vmode & FB_VMODE_INTERLACED) 2012 - tmp &= PIPE_A_EVENT_INTERRUPT; 2013 - else 2014 - tmp &= VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */ 2015 - 2016 - if (tmp == 0) { 2017 - spin_unlock(&dinfo->int_lock); 2018 - return IRQ_RETVAL(0); /* not us */ 2019 - } 2020 - 2021 - /* clear status bits 0-15 ASAP and don't touch bits 16-31 */ 2022 - OUTREG(PIPEASTAT, INREG(PIPEASTAT)); 2023 - 2024 - OUTREG16(IIR, tmp); 2025 - if (dinfo->vsync.pan_display) { 2026 - dinfo->vsync.pan_display = 0; 2027 - OUTREG(DSPABASE, dinfo->vsync.pan_offset); 2028 - } 2029 - 2030 - dinfo->vsync.count++; 2031 - wake_up_interruptible(&dinfo->vsync.wait); 2032 - 2033 - spin_unlock(&dinfo->int_lock); 2034 - 2035 - return IRQ_RETVAL(1); 2036 - } 2037 - 2038 - int intelfbhw_enable_irq(struct intelfb_info *dinfo) 2039 - { 2040 - u16 tmp; 2041 - if (!test_and_set_bit(0, &dinfo->irq_flags)) { 2042 - if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED, 2043 - "intelfb", dinfo)) { 2044 - clear_bit(0, &dinfo->irq_flags); 2045 - return -EINVAL; 2046 - } 2047 - 2048 - spin_lock_irq(&dinfo->int_lock); 2049 - OUTREG16(HWSTAM, 0xfffe); /* i830 DRM uses ffff */ 2050 - OUTREG16(IMR, 0); 2051 - } else 2052 - spin_lock_irq(&dinfo->int_lock); 2053 - 2054 - if (dinfo->info->var.vmode & FB_VMODE_INTERLACED) 2055 - tmp = PIPE_A_EVENT_INTERRUPT; 2056 - else 2057 - tmp = VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */ 2058 - if (tmp != INREG16(IER)) { 2059 - DBG_MSG("changing IER to 0x%X\n", tmp); 2060 - OUTREG16(IER, tmp); 2061 - } 2062 - 2063 - spin_unlock_irq(&dinfo->int_lock); 2064 - return 0; 2065 - } 2066 - 2067 - void intelfbhw_disable_irq(struct intelfb_info *dinfo) 2068 - { 2069 - if (test_and_clear_bit(0, &dinfo->irq_flags)) { 2070 - if (dinfo->vsync.pan_display) { 2071 - dinfo->vsync.pan_display = 0; 2072 - OUTREG(DSPABASE, dinfo->vsync.pan_offset); 2073 - } 2074 - spin_lock_irq(&dinfo->int_lock); 2075 - OUTREG16(HWSTAM, 0xffff); 2076 - OUTREG16(IMR, 0xffff); 2077 - OUTREG16(IER, 0x0); 2078 - 2079 - OUTREG16(IIR, INREG16(IIR)); /* clear IRQ requests */ 2080 - spin_unlock_irq(&dinfo->int_lock); 2081 - 2082 - free_irq(dinfo->pdev->irq, dinfo); 2083 - } 2084 - } 2085 - 2086 - int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) 2087 - { 2088 - struct intelfb_vsync *vsync; 2089 - unsigned int count; 2090 - int ret; 2091 - 2092 - switch (pipe) { 2093 - case 0: 2094 - vsync = &dinfo->vsync; 2095 - break; 2096 - default: 2097 - return -ENODEV; 2098 - } 2099 - 2100 - ret = intelfbhw_enable_irq(dinfo); 2101 - if (ret) 2102 - return ret; 2103 - 2104 - count = vsync->count; 2105 - ret = wait_event_interruptible_timeout(vsync->wait, 2106 - count != vsync->count, HZ / 10); 2107 - if (ret < 0) 2108 - return ret; 2109 - if (ret == 0) { 2110 - DBG_MSG("wait_for_vsync timed out!\n"); 2111 - return -ETIMEDOUT; 2112 - } 2113 - 2114 - return 0; 2115 - }
-609
drivers/video/fbdev/intelfb/intelfbhw.h
··· 1 - #ifndef _INTELFBHW_H 2 - #define _INTELFBHW_H 3 - 4 - /* $DHD: intelfb/intelfbhw.h,v 1.5 2003/06/27 15:06:25 dawes Exp $ */ 5 - 6 - 7 - /*** HW-specific data ***/ 8 - 9 - /* Information about the 852GM/855GM variants */ 10 - #define INTEL_85X_CAPID 0x44 11 - #define INTEL_85X_VARIANT_MASK 0x7 12 - #define INTEL_85X_VARIANT_SHIFT 5 13 - #define INTEL_VAR_855GME 0x0 14 - #define INTEL_VAR_855GM 0x4 15 - #define INTEL_VAR_852GME 0x2 16 - #define INTEL_VAR_852GM 0x5 17 - 18 - /* Information about DVO/LVDS Ports */ 19 - #define DVOA_PORT 0x1 20 - #define DVOB_PORT 0x2 21 - #define DVOC_PORT 0x4 22 - #define LVDS_PORT 0x8 23 - 24 - /* 25 - * The Bridge device's PCI config space has information about the 26 - * fb aperture size and the amount of pre-reserved memory. 27 - */ 28 - #define INTEL_GMCH_CTRL 0x52 29 - #define INTEL_GMCH_ENABLED 0x4 30 - #define INTEL_GMCH_MEM_MASK 0x1 31 - #define INTEL_GMCH_MEM_64M 0x1 32 - #define INTEL_GMCH_MEM_128M 0 33 - 34 - #define INTEL_830_GMCH_GMS_MASK (0x7 << 4) 35 - #define INTEL_830_GMCH_GMS_DISABLED (0x0 << 4) 36 - #define INTEL_830_GMCH_GMS_LOCAL (0x1 << 4) 37 - #define INTEL_830_GMCH_GMS_STOLEN_512 (0x2 << 4) 38 - #define INTEL_830_GMCH_GMS_STOLEN_1024 (0x3 << 4) 39 - #define INTEL_830_GMCH_GMS_STOLEN_8192 (0x4 << 4) 40 - 41 - #define INTEL_855_GMCH_GMS_MASK (0x7 << 4) 42 - #define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4) 43 - #define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4) 44 - #define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4) 45 - #define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4) 46 - #define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4) 47 - #define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4) 48 - 49 - #define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4) 50 - #define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4) 51 - 52 - /* HW registers */ 53 - 54 - /* Fence registers */ 55 - #define FENCE 0x2000 56 - #define FENCE_NUM 8 57 - 58 - /* Primary ring buffer */ 59 - #define PRI_RING_TAIL 0x2030 60 - #define RING_TAIL_MASK 0x001ffff8 61 - #define RING_INUSE 0x1 62 - 63 - #define PRI_RING_HEAD 0x2034 64 - #define RING_HEAD_WRAP_MASK 0x7ff 65 - #define RING_HEAD_WRAP_SHIFT 21 66 - #define RING_HEAD_MASK 0x001ffffc 67 - 68 - #define PRI_RING_START 0x2038 69 - #define RING_START_MASK 0xfffff000 70 - 71 - #define PRI_RING_LENGTH 0x203c 72 - #define RING_LENGTH_MASK 0x001ff000 73 - #define RING_REPORT_MASK (0x3 << 1) 74 - #define RING_NO_REPORT (0x0 << 1) 75 - #define RING_REPORT_64K (0x1 << 1) 76 - #define RING_REPORT_4K (0x2 << 1) 77 - #define RING_REPORT_128K (0x3 << 1) 78 - #define RING_ENABLE 0x1 79 - 80 - /* 81 - * Tail can't wrap to any closer than RING_MIN_FREE bytes of the head, 82 - * and the last RING_MIN_FREE bytes need to be padded with MI_NOOP 83 - */ 84 - #define RING_MIN_FREE 64 85 - 86 - #define IPEHR 0x2088 87 - 88 - #define INSTDONE 0x2090 89 - #define PRI_RING_EMPTY 1 90 - 91 - #define HWSTAM 0x2098 92 - #define IER 0x20A0 93 - #define IIR 0x20A4 94 - #define IMR 0x20A8 95 - #define VSYNC_PIPE_A_INTERRUPT (1 << 7) 96 - #define PIPE_A_EVENT_INTERRUPT (1 << 6) 97 - #define VSYNC_PIPE_B_INTERRUPT (1 << 5) 98 - #define PIPE_B_EVENT_INTERRUPT (1 << 4) 99 - #define HOST_PORT_EVENT_INTERRUPT (1 << 3) 100 - #define CAPTURE_EVENT_INTERRUPT (1 << 2) 101 - #define USER_DEFINED_INTERRUPT (1 << 1) 102 - #define BREAKPOINT_INTERRUPT 1 103 - 104 - #define INSTPM 0x20c0 105 - #define SYNC_FLUSH_ENABLE (1 << 5) 106 - 107 - #define INSTPS 0x20c4 108 - 109 - #define MEM_MODE 0x20cc 110 - 111 - #define MASK_SHIFT 16 112 - 113 - #define FW_BLC_0 0x20d8 114 - #define FW_DISPA_WM_SHIFT 0 115 - #define FW_DISPA_WM_MASK 0x3f 116 - #define FW_DISPA_BL_SHIFT 8 117 - #define FW_DISPA_BL_MASK 0xf 118 - #define FW_DISPB_WM_SHIFT 16 119 - #define FW_DISPB_WM_MASK 0x1f 120 - #define FW_DISPB_BL_SHIFT 24 121 - #define FW_DISPB_BL_MASK 0x7 122 - 123 - #define FW_BLC_1 0x20dc 124 - #define FW_DISPC_WM_SHIFT 0 125 - #define FW_DISPC_WM_MASK 0x1f 126 - #define FW_DISPC_BL_SHIFT 8 127 - #define FW_DISPC_BL_MASK 0x7 128 - 129 - #define GPIOA 0x5010 130 - #define GPIOB 0x5014 131 - #define GPIOC 0x5018 /* this may be external DDC on i830 */ 132 - #define GPIOD 0x501C /* this is DVO DDC */ 133 - #define GPIOE 0x5020 /* this is DVO i2C */ 134 - #define GPIOF 0x5024 135 - 136 - /* PLL registers */ 137 - #define VGA0_DIVISOR 0x06000 138 - #define VGA1_DIVISOR 0x06004 139 - #define VGAPD 0x06010 140 - #define VGAPD_0_P1_SHIFT 0 141 - #define VGAPD_0_P1_FORCE_DIV2 (1 << 5) 142 - #define VGAPD_0_P2_SHIFT 7 143 - #define VGAPD_1_P1_SHIFT 8 144 - #define VGAPD_1_P1_FORCE_DIV2 (1 << 13) 145 - #define VGAPD_1_P2_SHIFT 15 146 - 147 - #define DPLL_A 0x06014 148 - #define DPLL_B 0x06018 149 - #define DPLL_VCO_ENABLE (1 << 31) 150 - #define DPLL_2X_CLOCK_ENABLE (1 << 30) 151 - #define DPLL_SYNCLOCK_ENABLE (1 << 29) 152 - #define DPLL_VGA_MODE_DISABLE (1 << 28) 153 - #define DPLL_P2_MASK 1 154 - #define DPLL_P2_SHIFT 23 155 - #define DPLL_I9XX_P2_SHIFT 24 156 - #define DPLL_P1_FORCE_DIV2 (1 << 21) 157 - #define DPLL_P1_MASK 0x1f 158 - #define DPLL_P1_SHIFT 16 159 - #define DPLL_REFERENCE_SELECT_MASK (0x3 << 13) 160 - #define DPLL_REFERENCE_DEFAULT (0x0 << 13) 161 - #define DPLL_REFERENCE_TVCLK (0x2 << 13) 162 - #define DPLL_RATE_SELECT_MASK (1 << 8) 163 - #define DPLL_RATE_SELECT_FP0 (0 << 8) 164 - #define DPLL_RATE_SELECT_FP1 (1 << 8) 165 - 166 - #define FPA0 0x06040 167 - #define FPA1 0x06044 168 - #define FPB0 0x06048 169 - #define FPB1 0x0604c 170 - #define FP_DIVISOR_MASK 0x3f 171 - #define FP_N_DIVISOR_SHIFT 16 172 - #define FP_M1_DIVISOR_SHIFT 8 173 - #define FP_M2_DIVISOR_SHIFT 0 174 - 175 - /* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */ 176 - /* Clock values are in units of kHz */ 177 - #define PLL_REFCLK 48000 178 - #define MIN_CLOCK 25000 179 - #define MAX_CLOCK 350000 180 - 181 - /* Two pipes */ 182 - #define PIPE_A 0 183 - #define PIPE_B 1 184 - #define PIPE_MASK 1 185 - 186 - /* palette registers */ 187 - #define PALETTE_A 0x0a000 188 - #define PALETTE_B 0x0a800 189 - #ifndef PALETTE_8_ENTRIES 190 - #define PALETTE_8_ENTRIES 256 191 - #endif 192 - #define PALETTE_8_SIZE (PALETTE_8_ENTRIES * 4) 193 - #define PALETTE_10_ENTRIES 128 194 - #define PALETTE_10_SIZE (PALETTE_10_ENTRIES * 8) 195 - #define PALETTE_8_MASK 0xff 196 - #define PALETTE_8_RED_SHIFT 16 197 - #define PALETTE_8_GREEN_SHIFT 8 198 - #define PALETTE_8_BLUE_SHIFT 0 199 - 200 - /* CRTC registers */ 201 - #define HTOTAL_A 0x60000 202 - #define HBLANK_A 0x60004 203 - #define HSYNC_A 0x60008 204 - #define VTOTAL_A 0x6000c 205 - #define VBLANK_A 0x60010 206 - #define VSYNC_A 0x60014 207 - #define SRC_SIZE_A 0x6001c 208 - #define BCLRPAT_A 0x60020 209 - 210 - #define HTOTAL_B 0x61000 211 - #define HBLANK_B 0x61004 212 - #define HSYNC_B 0x61008 213 - #define VTOTAL_B 0x6100c 214 - #define VBLANK_B 0x61010 215 - #define VSYNC_B 0x61014 216 - #define SRC_SIZE_B 0x6101c 217 - #define BCLRPAT_B 0x61020 218 - 219 - #define HTOTAL_MASK 0xfff 220 - #define HTOTAL_SHIFT 16 221 - #define HACTIVE_MASK 0x7ff 222 - #define HACTIVE_SHIFT 0 223 - #define HBLANKEND_MASK 0xfff 224 - #define HBLANKEND_SHIFT 16 225 - #define HBLANKSTART_MASK 0xfff 226 - #define HBLANKSTART_SHIFT 0 227 - #define HSYNCEND_MASK 0xfff 228 - #define HSYNCEND_SHIFT 16 229 - #define HSYNCSTART_MASK 0xfff 230 - #define HSYNCSTART_SHIFT 0 231 - #define VTOTAL_MASK 0xfff 232 - #define VTOTAL_SHIFT 16 233 - #define VACTIVE_MASK 0x7ff 234 - #define VACTIVE_SHIFT 0 235 - #define VBLANKEND_MASK 0xfff 236 - #define VBLANKEND_SHIFT 16 237 - #define VBLANKSTART_MASK 0xfff 238 - #define VBLANKSTART_SHIFT 0 239 - #define VSYNCEND_MASK 0xfff 240 - #define VSYNCEND_SHIFT 16 241 - #define VSYNCSTART_MASK 0xfff 242 - #define VSYNCSTART_SHIFT 0 243 - #define SRC_SIZE_HORIZ_MASK 0x7ff 244 - #define SRC_SIZE_HORIZ_SHIFT 16 245 - #define SRC_SIZE_VERT_MASK 0x7ff 246 - #define SRC_SIZE_VERT_SHIFT 0 247 - 248 - #define ADPA 0x61100 249 - #define ADPA_DAC_ENABLE (1 << 31) 250 - #define ADPA_DAC_DISABLE 0 251 - #define ADPA_PIPE_SELECT_SHIFT 30 252 - #define ADPA_USE_VGA_HVPOLARITY (1 << 15) 253 - #define ADPA_SETS_HVPOLARITY 0 254 - #define ADPA_DPMS_CONTROL_MASK (0x3 << 10) 255 - #define ADPA_DPMS_D0 (0x0 << 10) 256 - #define ADPA_DPMS_D2 (0x1 << 10) 257 - #define ADPA_DPMS_D1 (0x2 << 10) 258 - #define ADPA_DPMS_D3 (0x3 << 10) 259 - #define ADPA_VSYNC_ACTIVE_SHIFT 4 260 - #define ADPA_HSYNC_ACTIVE_SHIFT 3 261 - #define ADPA_SYNC_ACTIVE_MASK 1 262 - #define ADPA_SYNC_ACTIVE_HIGH 1 263 - #define ADPA_SYNC_ACTIVE_LOW 0 264 - 265 - #define DVOA 0x61120 266 - #define DVOB 0x61140 267 - #define DVOC 0x61160 268 - #define LVDS 0x61180 269 - #define PORT_ENABLE (1 << 31) 270 - #define PORT_PIPE_SELECT_SHIFT 30 271 - #define PORT_TV_FLAGS_MASK 0xFF 272 - #define PORT_TV_FLAGS 0xC4 /* ripped from my BIOS 273 - to understand and correct */ 274 - 275 - #define DVOA_SRCDIM 0x61124 276 - #define DVOB_SRCDIM 0x61144 277 - #define DVOC_SRCDIM 0x61164 278 - 279 - #define PIPEA_DSL 0x70000 280 - #define PIPEB_DSL 0x71000 281 - #define PIPEACONF 0x70008 282 - #define PIPEBCONF 0x71008 283 - #define PIPEASTAT 0x70024 /* bits 0-15 are "write 1 to clear" */ 284 - #define PIPEBSTAT 0x71024 285 - 286 - #define PIPECONF_ENABLE (1 << 31) 287 - #define PIPECONF_DISABLE 0 288 - #define PIPECONF_DOUBLE_WIDE (1 << 30) 289 - #define PIPECONF_SINGLE_WIDE 0 290 - #define PIPECONF_LOCKED (1 << 25) 291 - #define PIPECONF_UNLOCKED 0 292 - #define PIPECONF_GAMMA (1 << 24) 293 - #define PIPECONF_PALETTE 0 294 - #define PIPECONF_PROGRESSIVE (0 << 21) 295 - #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) 296 - #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) 297 - #define PIPECONF_INTERLACE_MASK (7 << 21) 298 - 299 - /* enable bits, write 1 to enable */ 300 - #define PIPESTAT_FIFO_UNDERRUN (1 << 31) 301 - #define PIPESTAT_CRC_ERROR_EN (1 << 29) 302 - #define PIPESTAT_CRC_DONE_EN (1 << 28) 303 - #define PIPESTAT_HOTPLUG_EN (1 << 26) 304 - #define PIPESTAT_VERTICAL_SYNC_EN (1 << 25) 305 - #define PIPESTAT_DISPLINE_COMP_EN (1 << 24) 306 - #define PIPESTAT_FLD_EVT_ODD_EN (1 << 21) 307 - #define PIPESTAT_FLD_EVT_EVEN_EN (1 << 20) 308 - #define PIPESTAT_TV_HOTPLUG_EN (1 << 18) 309 - #define PIPESTAT_VBLANK_EN (1 << 17) 310 - #define PIPESTAT_OVL_UPDATE_EN (1 << 16) 311 - /* status bits, write 1 to clear */ 312 - #define PIPESTAT_HOTPLUG_STATE (1 << 15) 313 - #define PIPESTAT_CRC_ERROR (1 << 13) 314 - #define PIPESTAT_CRC_DONE (1 << 12) 315 - #define PIPESTAT_HOTPLUG (1 << 10) 316 - #define PIPESTAT_VSYNC (1 << 9) 317 - #define PIPESTAT_DISPLINE_COMP (1 << 8) 318 - #define PIPESTAT_FLD_EVT_ODD (1 << 5) 319 - #define PIPESTAT_FLD_EVT_EVEN (1 << 4) 320 - #define PIPESTAT_TV_HOTPLUG (1 << 2) 321 - #define PIPESTAT_VBLANK (1 << 1) 322 - #define PIPESTAT_OVL_UPDATE (1 << 0) 323 - 324 - #define DISPARB 0x70030 325 - #define DISPARB_AEND_MASK 0x1ff 326 - #define DISPARB_AEND_SHIFT 0 327 - #define DISPARB_BEND_MASK 0x3ff 328 - #define DISPARB_BEND_SHIFT 9 329 - 330 - /* Desktop HW cursor */ 331 - #define CURSOR_CONTROL 0x70080 332 - #define CURSOR_ENABLE (1 << 31) 333 - #define CURSOR_GAMMA_ENABLE (1 << 30) 334 - #define CURSOR_STRIDE_MASK (0x3 << 28) 335 - #define CURSOR_STRIDE_256 (0x0 << 28) 336 - #define CURSOR_STRIDE_512 (0x1 << 28) 337 - #define CURSOR_STRIDE_1K (0x2 << 28) 338 - #define CURSOR_STRIDE_2K (0x3 << 28) 339 - #define CURSOR_FORMAT_MASK (0x7 << 24) 340 - #define CURSOR_FORMAT_2C (0x0 << 24) 341 - #define CURSOR_FORMAT_3C (0x1 << 24) 342 - #define CURSOR_FORMAT_4C (0x2 << 24) 343 - #define CURSOR_FORMAT_ARGB (0x4 << 24) 344 - #define CURSOR_FORMAT_XRGB (0x5 << 24) 345 - 346 - /* Mobile HW cursor (and i810) */ 347 - #define CURSOR_A_CONTROL CURSOR_CONTROL 348 - #define CURSOR_B_CONTROL 0x700c0 349 - #define CURSOR_MODE_MASK 0x27 350 - #define CURSOR_MODE_DISABLE 0 351 - #define CURSOR_MODE_64_3C 0x04 352 - #define CURSOR_MODE_64_4C_AX 0x05 353 - #define CURSOR_MODE_64_4C 0x06 354 - #define CURSOR_MODE_64_32B_AX 0x07 355 - #define CURSOR_MODE_64_ARGB_AX 0x27 356 - #define CURSOR_PIPE_SELECT_SHIFT 28 357 - #define CURSOR_MOBILE_GAMMA_ENABLE (1 << 26) 358 - #define CURSOR_MEM_TYPE_LOCAL (1 << 25) 359 - 360 - /* All platforms (desktop has no pipe B) */ 361 - #define CURSOR_A_BASEADDR 0x70084 362 - #define CURSOR_B_BASEADDR 0x700c4 363 - #define CURSOR_BASE_MASK 0xffffff00 364 - 365 - #define CURSOR_A_POSITION 0x70088 366 - #define CURSOR_B_POSITION 0x700c8 367 - #define CURSOR_POS_SIGN (1 << 15) 368 - #define CURSOR_POS_MASK 0x7ff 369 - #define CURSOR_X_SHIFT 0 370 - #define CURSOR_Y_SHIFT 16 371 - 372 - #define CURSOR_A_PALETTE0 0x70090 373 - #define CURSOR_A_PALETTE1 0x70094 374 - #define CURSOR_A_PALETTE2 0x70098 375 - #define CURSOR_A_PALETTE3 0x7009c 376 - #define CURSOR_B_PALETTE0 0x700d0 377 - #define CURSOR_B_PALETTE1 0x700d4 378 - #define CURSOR_B_PALETTE2 0x700d8 379 - #define CURSOR_B_PALETTE3 0x700dc 380 - #define CURSOR_COLOR_MASK 0xff 381 - #define CURSOR_RED_SHIFT 16 382 - #define CURSOR_GREEN_SHIFT 8 383 - #define CURSOR_BLUE_SHIFT 0 384 - #define CURSOR_PALETTE_MASK 0xffffff 385 - 386 - /* Desktop only */ 387 - #define CURSOR_SIZE 0x700a0 388 - #define CURSOR_SIZE_MASK 0x3ff 389 - #define CURSOR_SIZE_H_SHIFT 0 390 - #define CURSOR_SIZE_V_SHIFT 12 391 - 392 - #define DSPACNTR 0x70180 393 - #define DSPBCNTR 0x71180 394 - #define DISPPLANE_PLANE_ENABLE (1 << 31) 395 - #define DISPPLANE_PLANE_DISABLE 0 396 - #define DISPPLANE_GAMMA_ENABLE (1<<30) 397 - #define DISPPLANE_GAMMA_DISABLE 0 398 - #define DISPPLANE_PIXFORMAT_MASK (0xf<<26) 399 - #define DISPPLANE_8BPP (0x2<<26) 400 - #define DISPPLANE_15_16BPP (0x4<<26) 401 - #define DISPPLANE_16BPP (0x5<<26) 402 - #define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) 403 - #define DISPPLANE_32BPP (0x7<<26) 404 - #define DISPPLANE_STEREO_ENABLE (1<<25) 405 - #define DISPPLANE_STEREO_DISABLE 0 406 - #define DISPPLANE_SEL_PIPE_SHIFT 24 407 - #define DISPPLANE_SRC_KEY_ENABLE (1<<22) 408 - #define DISPPLANE_SRC_KEY_DISABLE 0 409 - #define DISPPLANE_LINE_DOUBLE (1<<20) 410 - #define DISPPLANE_NO_LINE_DOUBLE 0 411 - #define DISPPLANE_STEREO_POLARITY_FIRST 0 412 - #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) 413 - /* plane B only */ 414 - #define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) 415 - #define DISPPLANE_ALPHA_TRANS_DISABLE 0 416 - #define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 417 - #define DISPPLANE_SPRITE_ABOVE_OVERLAY 1 418 - 419 - #define DSPABASE 0x70184 420 - #define DSPASTRIDE 0x70188 421 - 422 - #define DSPBBASE 0x71184 423 - #define DSPBSTRIDE 0x71188 424 - 425 - #define VGACNTRL 0x71400 426 - #define VGA_DISABLE (1 << 31) 427 - #define VGA_ENABLE 0 428 - #define VGA_PIPE_SELECT_SHIFT 29 429 - #define VGA_PALETTE_READ_SELECT 23 430 - #define VGA_PALETTE_A_WRITE_DISABLE (1 << 22) 431 - #define VGA_PALETTE_B_WRITE_DISABLE (1 << 21) 432 - #define VGA_LEGACY_PALETTE (1 << 20) 433 - #define VGA_6BIT_DAC 0 434 - #define VGA_8BIT_DAC (1 << 20) 435 - 436 - #define ADD_ID 0x71408 437 - #define ADD_ID_MASK 0xff 438 - 439 - /* BIOS scratch area registers (830M and 845G). */ 440 - #define SWF0 0x71410 441 - #define SWF1 0x71414 442 - #define SWF2 0x71418 443 - #define SWF3 0x7141c 444 - #define SWF4 0x71420 445 - #define SWF5 0x71424 446 - #define SWF6 0x71428 447 - 448 - /* BIOS scratch area registers (852GM, 855GM, 865G). */ 449 - #define SWF00 0x70410 450 - #define SWF01 0x70414 451 - #define SWF02 0x70418 452 - #define SWF03 0x7041c 453 - #define SWF04 0x70420 454 - #define SWF05 0x70424 455 - #define SWF06 0x70428 456 - 457 - #define SWF10 SWF0 458 - #define SWF11 SWF1 459 - #define SWF12 SWF2 460 - #define SWF13 SWF3 461 - #define SWF14 SWF4 462 - #define SWF15 SWF5 463 - #define SWF16 SWF6 464 - 465 - #define SWF30 0x72414 466 - #define SWF31 0x72418 467 - #define SWF32 0x7241c 468 - 469 - /* Memory Commands */ 470 - #define MI_NOOP (0x00 << 23) 471 - #define MI_NOOP_WRITE_ID (1 << 22) 472 - #define MI_NOOP_ID_MASK ((1 << 22) - 1) 473 - 474 - #define MI_FLUSH (0x04 << 23) 475 - #define MI_WRITE_DIRTY_STATE (1 << 4) 476 - #define MI_END_SCENE (1 << 3) 477 - #define MI_INHIBIT_RENDER_CACHE_FLUSH (1 << 2) 478 - #define MI_INVALIDATE_MAP_CACHE (1 << 0) 479 - 480 - #define MI_STORE_DWORD_IMM ((0x20 << 23) | 1) 481 - 482 - /* 2D Commands */ 483 - #define COLOR_BLT_CMD ((2 << 29) | (0x40 << 22) | 3) 484 - #define XY_COLOR_BLT_CMD ((2 << 29) | (0x50 << 22) | 4) 485 - #define XY_SETUP_CLIP_BLT_CMD ((2 << 29) | (0x03 << 22) | 1) 486 - #define XY_SRC_COPY_BLT_CMD ((2 << 29) | (0x53 << 22) | 6) 487 - #define SRC_COPY_BLT_CMD ((2 << 29) | (0x43 << 22) | 4) 488 - #define XY_MONO_PAT_BLT_CMD ((2 << 29) | (0x52 << 22) | 7) 489 - #define XY_MONO_SRC_BLT_CMD ((2 << 29) | (0x54 << 22) | 6) 490 - #define XY_MONO_SRC_IMM_BLT_CMD ((2 << 29) | (0x71 << 22) | 5) 491 - #define TXT_IMM_BLT_CMD ((2 << 29) | (0x30 << 22) | 2) 492 - #define SETUP_BLT_CMD ((2 << 29) | (0x00 << 22) | 6) 493 - 494 - #define DW_LENGTH_MASK 0xff 495 - 496 - #define WRITE_ALPHA (1 << 21) 497 - #define WRITE_RGB (1 << 20) 498 - #define VERT_SEED (3 << 8) 499 - #define HORIZ_SEED (3 << 12) 500 - 501 - #define COLOR_DEPTH_8 (0 << 24) 502 - #define COLOR_DEPTH_16 (1 << 24) 503 - #define COLOR_DEPTH_32 (3 << 24) 504 - 505 - #define SRC_ROP_GXCOPY 0xcc 506 - #define SRC_ROP_GXXOR 0x66 507 - 508 - #define PAT_ROP_GXCOPY 0xf0 509 - #define PAT_ROP_GXXOR 0x5a 510 - 511 - #define PITCH_SHIFT 0 512 - #define ROP_SHIFT 16 513 - #define WIDTH_SHIFT 0 514 - #define HEIGHT_SHIFT 16 515 - 516 - /* in bytes */ 517 - #define MAX_MONO_IMM_SIZE 128 518 - 519 - 520 - /*** Macros ***/ 521 - 522 - /* I/O macros */ 523 - #define INREG8(addr) readb((u8 __iomem *)(dinfo->mmio_base + (addr))) 524 - #define INREG16(addr) readw((u16 __iomem *)(dinfo->mmio_base + (addr))) 525 - #define INREG(addr) readl((u32 __iomem *)(dinfo->mmio_base + (addr))) 526 - #define OUTREG8(addr, val) writeb((val),(u8 __iomem *)(dinfo->mmio_base + \ 527 - (addr))) 528 - #define OUTREG16(addr, val) writew((val),(u16 __iomem *)(dinfo->mmio_base + \ 529 - (addr))) 530 - #define OUTREG(addr, val) writel((val),(u32 __iomem *)(dinfo->mmio_base + \ 531 - (addr))) 532 - 533 - /* Ring buffer macros */ 534 - #define OUT_RING(n) do { \ 535 - writel((n), (u32 __iomem *)(dinfo->ring.virtual + dinfo->ring_tail));\ 536 - dinfo->ring_tail += 4; \ 537 - dinfo->ring_tail &= dinfo->ring_tail_mask; \ 538 - } while (0) 539 - 540 - #define START_RING(n) do { \ 541 - if (dinfo->ring_space < (n) * 4) \ 542 - wait_ring(dinfo,(n) * 4); \ 543 - dinfo->ring_space -= (n) * 4; \ 544 - } while (0) 545 - 546 - #define ADVANCE_RING() do { \ 547 - OUTREG(PRI_RING_TAIL, dinfo->ring_tail); \ 548 - } while (0) 549 - 550 - #define DO_RING_IDLE() do { \ 551 - u32 head, tail; \ 552 - do { \ 553 - head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; \ 554 - tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; \ 555 - udelay(10); \ 556 - } while (head != tail); \ 557 - } while (0) 558 - 559 - 560 - /* function protoypes */ 561 - extern int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo); 562 - extern int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, 563 - int *stolen_size); 564 - extern int intelfbhw_check_non_crt(struct intelfb_info *dinfo); 565 - extern const char *intelfbhw_dvo_to_string(int dvo); 566 - extern int intelfbhw_validate_mode(struct intelfb_info *dinfo, 567 - struct fb_var_screeninfo *var); 568 - extern int intelfbhw_pan_display(struct fb_var_screeninfo *var, 569 - struct fb_info *info); 570 - extern void intelfbhw_do_blank(int blank, struct fb_info *info); 571 - extern void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, 572 - unsigned red, unsigned green, unsigned blue, 573 - unsigned transp); 574 - extern int intelfbhw_read_hw_state(struct intelfb_info *dinfo, 575 - struct intelfb_hwstate *hw, int flag); 576 - extern void intelfbhw_print_hw_state(struct intelfb_info *dinfo, 577 - struct intelfb_hwstate *hw); 578 - extern int intelfbhw_mode_to_hw(struct intelfb_info *dinfo, 579 - struct intelfb_hwstate *hw, 580 - struct fb_var_screeninfo *var); 581 - extern int intelfbhw_program_mode(struct intelfb_info *dinfo, 582 - const struct intelfb_hwstate *hw, int blank); 583 - extern void intelfbhw_do_sync(struct intelfb_info *dinfo); 584 - extern void intelfbhw_2d_stop(struct intelfb_info *dinfo); 585 - extern void intelfbhw_2d_start(struct intelfb_info *dinfo); 586 - extern void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, 587 - u32 w, u32 h, u32 color, u32 pitch, u32 bpp, 588 - u32 rop); 589 - extern void intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury, 590 - u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch, 591 - u32 bpp); 592 - extern int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, 593 - u32 w, u32 h, const u8* cdat, u32 x, u32 y, 594 - u32 pitch, u32 bpp); 595 - extern void intelfbhw_cursor_init(struct intelfb_info *dinfo); 596 - extern void intelfbhw_cursor_hide(struct intelfb_info *dinfo); 597 - extern void intelfbhw_cursor_show(struct intelfb_info *dinfo); 598 - extern void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y); 599 - extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, 600 - u32 fg); 601 - extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, 602 - int height, u8 *data); 603 - extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo); 604 - extern int intelfbhw_enable_irq(struct intelfb_info *dinfo); 605 - extern void intelfbhw_disable_irq(struct intelfb_info *dinfo); 606 - extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe); 607 - extern int intelfbhw_active_pipe(const struct intelfb_hwstate *hw); 608 - 609 - #endif /* _INTELFBHW_H */
+1 -1
drivers/video/fbdev/mmp/hw/mmp_spi.c
··· 91 91 writel(tmp, reg_base + LCD_SPU_SPI_CTRL); 92 92 93 93 /* 94 - * After set mode it need a time to pull up the spi singals, 94 + * After set mode it needs some time to pull up the spi signals, 95 95 * or it would cause the wrong waveform when send spi command, 96 96 * especially on pxa910h 97 97 */
-37
drivers/video/fbdev/sis/sis_main.c
··· 27 27 #include <linux/errno.h> 28 28 #include <linux/string.h> 29 29 #include <linux/mm.h> 30 - #include <linux/screen_info.h> 31 30 #include <linux/slab.h> 32 31 #include <linux/fb.h> 33 32 #include <linux/selection.h> ··· 255 256 if((!j) && !quiet) 256 257 printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr); 257 258 } 258 - 259 - #ifndef MODULE 260 - static void sisfb_get_vga_mode_from_kernel(void) 261 - { 262 - #ifdef CONFIG_X86 263 - char mymode[32]; 264 - int mydepth = screen_info.lfb_depth; 265 - 266 - if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return; 267 - 268 - if( (screen_info.lfb_width >= 320) && (screen_info.lfb_width <= 2048) && 269 - (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) && 270 - (mydepth >= 8) && (mydepth <= 32) ) { 271 - 272 - if(mydepth == 24) mydepth = 32; 273 - 274 - sprintf(mymode, "%ux%ux%u", screen_info.lfb_width, 275 - screen_info.lfb_height, 276 - mydepth); 277 - 278 - printk(KERN_DEBUG 279 - "sisfb: Using vga mode %s pre-set by kernel as default\n", 280 - mymode); 281 - 282 - sisfb_search_mode(mymode, true); 283 - } 284 - #endif 285 - return; 286 - } 287 - #endif 288 259 289 260 static void __init 290 261 sisfb_search_crt2type(const char *name) ··· 5869 5900 ivideo->pcifunc = PCI_FUNC(pdev->devfn); 5870 5901 ivideo->subsysvendor = pdev->subsystem_vendor; 5871 5902 ivideo->subsysdevice = pdev->subsystem_device; 5872 - 5873 - #ifndef MODULE 5874 - if(sisfb_mode_idx == -1) { 5875 - sisfb_get_vga_mode_from_kernel(); 5876 - } 5877 - #endif 5878 5903 5879 5904 ivideo->chip = chipinfo->chip; 5880 5905 ivideo->chip_real_id = chipinfo->chip;
+56 -53
drivers/video/fbdev/stifb.c
··· 103 103 } ngle_rom_t; 104 104 105 105 struct stifb_info { 106 - struct fb_info info; 106 + struct fb_info *info; 107 107 unsigned int id; 108 108 ngle_rom_t ngle_rom; 109 109 struct sti_struct *sti; ··· 153 153 #define REG_44 0x210030 154 154 #define REG_45 0x210034 155 155 156 - #define READ_BYTE(fb,reg) gsc_readb((fb)->info.fix.mmio_start + (reg)) 157 - #define READ_WORD(fb,reg) gsc_readl((fb)->info.fix.mmio_start + (reg)) 156 + #define READ_BYTE(fb, reg) gsc_readb((fb)->info->fix.mmio_start + (reg)) 157 + #define READ_WORD(fb, reg) gsc_readl((fb)->info->fix.mmio_start + (reg)) 158 158 159 159 160 160 #ifndef DEBUG_STIFB_REGS 161 161 # define DEBUG_OFF() 162 162 # define DEBUG_ON() 163 - # define WRITE_BYTE(value,fb,reg) gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)) 164 - # define WRITE_WORD(value,fb,reg) gsc_writel((value),(fb)->info.fix.mmio_start + (reg)) 163 + # define WRITE_BYTE(value, fb, reg) gsc_writeb((value), (fb)->info->fix.mmio_start + (reg)) 164 + # define WRITE_WORD(value, fb, reg) gsc_writel((value), (fb)->info->fix.mmio_start + (reg)) 165 165 #else 166 166 static int debug_on = 1; 167 167 # define DEBUG_OFF() debug_on=0 ··· 169 169 # define WRITE_BYTE(value,fb,reg) do { if (debug_on) \ 170 170 printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \ 171 171 __func__, reg, value, READ_BYTE(fb,reg)); \ 172 - gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0) 172 + gsc_writeb((value), (fb)->info->fix.mmio_start + (reg)); } while (0) 173 173 # define WRITE_WORD(value,fb,reg) do { if (debug_on) \ 174 174 printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \ 175 175 __func__, reg, value, READ_WORD(fb,reg)); \ 176 - gsc_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0) 176 + gsc_writel((value), (fb)->info->fix.mmio_start + (reg)); } while (0) 177 177 #endif /* DEBUG_STIFB_REGS */ 178 178 179 179 ··· 210 210 reg10_value = 0x13601000; 211 211 break; 212 212 case S9000_ID_A1439A: 213 - if (fb->info.var.bits_per_pixel == 32) 213 + if (fb->info->var.bits_per_pixel == 32) 214 214 reg10_value = 0xBBA0A000; 215 215 else 216 216 reg10_value = 0x13601000; 217 217 break; 218 218 case S9000_ID_HCRX: 219 - if (fb->info.var.bits_per_pixel == 32) 219 + if (fb->info->var.bits_per_pixel == 32) 220 220 reg10_value = 0xBBA0A000; 221 221 else 222 222 reg10_value = 0x13602000; ··· 254 254 FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb) 255 255 { 256 256 WRITE_WORD(0x400, fb, REG_2); 257 - if (fb->info.var.bits_per_pixel == 32) { 257 + if (fb->info->var.bits_per_pixel == 32) { 258 258 WRITE_WORD(0x83000100, fb, REG_1); 259 259 } else { 260 260 if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG) ··· 503 503 ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber) 504 504 { 505 505 SETUP_ATTR_ACCESS(fb, BufferNumber); 506 - SET_ATTR_SIZE(fb, fb->info.var.xres, fb->info.var.yres); 506 + SET_ATTR_SIZE(fb, fb->info->var.xres, fb->info->var.yres); 507 507 FINISH_ATTR_ACCESS(fb); 508 508 SETUP_FB(fb); 509 509 } ··· 526 526 SETUP_FB(fb); 527 527 fb->id = saved_id; 528 528 529 - for (y = 0; y < fb->info.var.yres; ++y) 530 - fb_memset_io(fb->info.screen_base + y * fb->info.fix.line_length, 531 - 0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8); 529 + for (y = 0; y < fb->info->var.yres; ++y) 530 + fb_memset_io(fb->info->screen_base + y * fb->info->fix.line_length, 531 + 0xff, fb->info->var.xres * fb->info->var.bits_per_pixel/8); 532 532 533 533 CRX24_SET_OVLY_MASK(fb); 534 534 SETUP_FB(fb); ··· 607 607 lutBltCtl.fields.lutType = HYPER_CMAP_TYPE; 608 608 609 609 /* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */ 610 - if (fb->info.var.bits_per_pixel == 8) 610 + if (fb->info->var.bits_per_pixel == 8) 611 611 lutBltCtl.fields.lutOffset = 2 * 256; 612 612 else 613 613 lutBltCtl.fields.lutOffset = 0 * 256; ··· 688 688 DataDynamic, MaskOtc, 689 689 BGx(0), FGx(0))); 690 690 packed_dst = 0; 691 - packed_len = (fb->info.var.xres << 16) | fb->info.var.yres; 691 + packed_len = (fb->info->var.xres << 16) | fb->info->var.yres; 692 692 GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2); 693 693 NGLE_SET_DSTXY(fb, packed_dst); 694 694 SET_LENXY_START_RECFILL(fb, packed_len); ··· 738 738 NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask); 739 739 740 740 packed_dst = 0; 741 - packed_len = (fb->info.var.xres << 16) | fb->info.var.yres; 741 + packed_len = (fb->info->var.xres << 16) | fb->info->var.yres; 742 742 NGLE_SET_DSTXY(fb, packed_dst); 743 743 744 744 /* Write zeroes to overlay planes */ ··· 760 760 NGLE_LOCK(fb); 761 761 762 762 if (IS_24_DEVICE(fb)) 763 - if (fb->info.var.bits_per_pixel == 32) 763 + if (fb->info->var.bits_per_pixel == 32) 764 764 controlPlaneReg = 0x04000F00; 765 765 else 766 766 controlPlaneReg = 0x00000F00; /* 0x00000800 should be enough, but lets clear all 4 bits */ ··· 890 890 GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7); 891 891 892 892 if (IS_24_DEVICE(fb)) { 893 - hyperbowl = (fb->info.var.bits_per_pixel == 32) ? 893 + hyperbowl = (fb->info->var.bits_per_pixel == 32) ? 894 894 HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE : 895 895 HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE; 896 896 ··· 924 924 static int 925 925 stifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 926 926 { 927 - struct stifb_info *fb = container_of(info, struct stifb_info, info); 927 + struct stifb_info *fb = info->par; 928 928 929 - if (var->xres != fb->info.var.xres || 930 - var->yres != fb->info.var.yres || 931 - var->bits_per_pixel != fb->info.var.bits_per_pixel) 929 + if (var->xres != fb->info->var.xres || 930 + var->yres != fb->info->var.yres || 931 + var->bits_per_pixel != fb->info->var.bits_per_pixel) 932 932 return -EINVAL; 933 933 934 934 var->xres_virtual = var->xres; 935 935 var->yres_virtual = var->yres; 936 936 var->xoffset = 0; 937 937 var->yoffset = 0; 938 - var->grayscale = fb->info.var.grayscale; 939 - var->red.length = fb->info.var.red.length; 940 - var->green.length = fb->info.var.green.length; 941 - var->blue.length = fb->info.var.blue.length; 938 + var->grayscale = fb->info->var.grayscale; 939 + var->red.length = fb->info->var.red.length; 940 + var->green.length = fb->info->var.green.length; 941 + var->blue.length = fb->info->var.blue.length; 942 942 943 943 return 0; 944 944 } ··· 947 947 stifb_setcolreg(u_int regno, u_int red, u_int green, 948 948 u_int blue, u_int transp, struct fb_info *info) 949 949 { 950 - struct stifb_info *fb = container_of(info, struct stifb_info, info); 950 + struct stifb_info *fb = info->par; 951 951 u32 color; 952 952 953 953 if (regno >= NR_PALETTE) ··· 961 961 962 962 START_IMAGE_COLORMAP_ACCESS(fb); 963 963 964 - if (unlikely(fb->info.var.grayscale)) { 964 + if (unlikely(fb->info->var.grayscale)) { 965 965 /* gray = 0.30*R + 0.59*G + 0.11*B */ 966 966 color = ((red * 77) + 967 967 (green * 151) + ··· 972 972 (blue)); 973 973 } 974 974 975 - if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) { 976 - struct fb_var_screeninfo *var = &fb->info.var; 975 + if (fb->info->fix.visual == FB_VISUAL_DIRECTCOLOR) { 976 + struct fb_var_screeninfo *var = &fb->info->var; 977 977 if (regno < 16) 978 - ((u32 *)fb->info.pseudo_palette)[regno] = 978 + ((u32 *)fb->info->pseudo_palette)[regno] = 979 979 regno << var->red.offset | 980 980 regno << var->green.offset | 981 981 regno << var->blue.offset; ··· 1007 1007 static int 1008 1008 stifb_blank(int blank_mode, struct fb_info *info) 1009 1009 { 1010 - struct stifb_info *fb = container_of(info, struct stifb_info, info); 1010 + struct stifb_info *fb = info->par; 1011 1011 int enable = (blank_mode == 0) ? ENABLE : DISABLE; 1012 1012 1013 1013 switch (fb->id) { ··· 1036 1036 static void 1037 1037 stifb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 1038 1038 { 1039 - struct stifb_info *fb = container_of(info, struct stifb_info, info); 1039 + struct stifb_info *fb = info->par; 1040 1040 1041 1041 SETUP_COPYAREA(fb); 1042 1042 1043 1043 SETUP_HW(fb); 1044 - if (fb->info.var.bits_per_pixel == 32) { 1044 + if (fb->info->var.bits_per_pixel == 32) { 1045 1045 WRITE_WORD(0xBBA0A000, fb, REG_10); 1046 1046 1047 1047 NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff); ··· 1075 1075 static void 1076 1076 stifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 1077 1077 { 1078 - struct stifb_info *fb = container_of(info, struct stifb_info, info); 1078 + struct stifb_info *fb = info->par; 1079 1079 1080 1080 if (rect->rop != ROP_COPY || 1081 - (fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32)) 1081 + (fb->id == S9000_ID_HCRX && fb->info->var.bits_per_pixel == 32)) 1082 1082 return cfb_fillrect(info, rect); 1083 1083 1084 1084 SETUP_HW(fb); 1085 1085 1086 - if (fb->info.var.bits_per_pixel == 32) { 1086 + if (fb->info->var.bits_per_pixel == 32) { 1087 1087 WRITE_WORD(0xBBA0A000, fb, REG_10); 1088 1088 1089 1089 NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff); ··· 1141 1141 switch (id) { 1142 1142 case S9000_ID_A1659A: 1143 1143 case S9000_ID_A1439A: 1144 - if (fb->info.var.bits_per_pixel == 32) 1144 + if (fb->info->var.bits_per_pixel == 32) 1145 1145 ngleSetupAttrPlanes(fb, BUFF1_CMAP3); 1146 1146 else { 1147 1147 ngleSetupAttrPlanes(fb, BUFF1_CMAP0); ··· 1151 1151 break; 1152 1152 case S9000_ID_ARTIST: 1153 1153 case CRT_ID_VISUALIZE_EG: 1154 - if (fb->info.var.bits_per_pixel == 32) 1154 + if (fb->info->var.bits_per_pixel == 32) 1155 1155 ngleSetupAttrPlanes(fb, BUFF1_CMAP3); 1156 1156 else { 1157 1157 ngleSetupAttrPlanes(fb, ARTIST_CMAP0); ··· 1193 1193 char *dev_name; 1194 1194 int bpp, xres, yres; 1195 1195 1196 - fb = kzalloc(sizeof(*fb), GFP_ATOMIC); 1197 - if (!fb) 1196 + info = framebuffer_alloc(sizeof(*fb), sti->dev); 1197 + if (!info) 1198 1198 return -ENOMEM; 1199 - 1200 - info = &fb->info; 1199 + fb = info->par; 1200 + fb->info = info; 1201 1201 1202 1202 /* set struct to a known state */ 1203 1203 fix = &info->fix; ··· 1389 1389 } 1390 1390 1391 1391 /* save for primary gfx device detection & unregister_framebuffer() */ 1392 - sti->info = info; 1393 - if (register_framebuffer(&fb->info) < 0) 1392 + if (register_framebuffer(fb->info) < 0) 1394 1393 goto out_err4; 1395 1394 1396 - fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n", 1395 + fb_info(fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n", 1397 1396 fix->id, 1398 1397 var->xres, 1399 1398 var->yres, ··· 1400 1401 dev_name, 1401 1402 fb->id, 1402 1403 fix->mmio_start); 1404 + 1405 + dev_set_drvdata(sti->dev, info); 1403 1406 1404 1407 return 0; 1405 1408 ··· 1415 1414 out_err1: 1416 1415 iounmap(info->screen_base); 1417 1416 out_err0: 1418 - kfree(fb); 1419 - sti->info = NULL; 1417 + framebuffer_release(info); 1420 1418 return -ENXIO; 1421 1419 } 1422 1420 ··· 1480 1480 sti = sti_get_rom(i); 1481 1481 if (!sti) 1482 1482 break; 1483 - if (sti->info) { 1484 - struct fb_info *info = sti->info; 1485 - unregister_framebuffer(sti->info); 1483 + if (sti->dev) { 1484 + struct fb_info *info = dev_get_drvdata(sti->dev); 1485 + 1486 + if (!info) 1487 + continue; 1488 + unregister_framebuffer(info); 1486 1489 release_mem_region(info->fix.mmio_start, info->fix.mmio_len); 1487 1490 release_mem_region(info->fix.smem_start, info->fix.smem_len); 1488 1491 if (info->screen_base) 1489 1492 iounmap(info->screen_base); 1490 1493 fb_dealloc_cmap(&info->cmap); 1491 1494 framebuffer_release(info); 1495 + dev_set_drvdata(sti->dev, NULL); 1492 1496 } 1493 - sti->info = NULL; 1494 1497 } 1495 1498 } 1496 1499
-6
drivers/video/fbdev/vermilion/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - obj-$(CONFIG_FB_LE80578) += vmlfb.o 3 - obj-$(CONFIG_FB_CARILLO_RANCH) += crvml.o 4 - 5 - vmlfb-objs := vermilion.o 6 - crvml-objs := cr_pll.o
-195
drivers/video/fbdev/vermilion/cr_pll.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (c) Intel Corp. 2007. 4 - * All Rights Reserved. 5 - * 6 - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 7 - * develop this driver. 8 - * 9 - * This file is part of the Carillo Ranch video subsystem driver. 10 - * 11 - * Authors: 12 - * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> 13 - * Alan Hourihane <alanh-at-tungstengraphics-dot-com> 14 - */ 15 - 16 - #include <linux/module.h> 17 - #include <linux/kernel.h> 18 - #include <linux/pci.h> 19 - #include <linux/errno.h> 20 - #include <linux/fb.h> 21 - #include "vermilion.h" 22 - 23 - /* The PLL Clock register sits on Host bridge */ 24 - #define CRVML_DEVICE_MCH 0x5001 25 - #define CRVML_REG_MCHBAR 0x44 26 - #define CRVML_REG_MCHEN 0x54 27 - #define CRVML_MCHEN_BIT (1 << 28) 28 - #define CRVML_MCHMAP_SIZE 4096 29 - #define CRVML_REG_CLOCK 0xc3c 30 - #define CRVML_CLOCK_SHIFT 8 31 - #define CRVML_CLOCK_MASK 0x00000f00 32 - 33 - static struct pci_dev *mch_dev; 34 - static u32 mch_bar; 35 - static void __iomem *mch_regs_base; 36 - static u32 saved_clock; 37 - 38 - static const unsigned crvml_clocks[] = { 39 - 6750, 40 - 13500, 41 - 27000, 42 - 29700, 43 - 37125, 44 - 54000, 45 - 59400, 46 - 74250, 47 - 120000 48 - /* 49 - * There are more clocks, but they are disabled on the CR board. 50 - */ 51 - }; 52 - 53 - static const u32 crvml_clock_bits[] = { 54 - 0x0a, 55 - 0x09, 56 - 0x08, 57 - 0x07, 58 - 0x06, 59 - 0x05, 60 - 0x04, 61 - 0x03, 62 - 0x0b 63 - }; 64 - 65 - static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks); 66 - 67 - static int crvml_sys_restore(struct vml_sys *sys) 68 - { 69 - void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; 70 - 71 - iowrite32(saved_clock, clock_reg); 72 - ioread32(clock_reg); 73 - 74 - return 0; 75 - } 76 - 77 - static int crvml_sys_save(struct vml_sys *sys) 78 - { 79 - void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; 80 - 81 - saved_clock = ioread32(clock_reg); 82 - 83 - return 0; 84 - } 85 - 86 - static int crvml_nearest_index(const struct vml_sys *sys, int clock) 87 - { 88 - int i; 89 - int cur_index = 0; 90 - int cur_diff; 91 - int diff; 92 - 93 - cur_diff = clock - crvml_clocks[0]; 94 - cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; 95 - for (i = 1; i < crvml_num_clocks; ++i) { 96 - diff = clock - crvml_clocks[i]; 97 - diff = (diff < 0) ? -diff : diff; 98 - if (diff < cur_diff) { 99 - cur_index = i; 100 - cur_diff = diff; 101 - } 102 - } 103 - return cur_index; 104 - } 105 - 106 - static int crvml_nearest_clock(const struct vml_sys *sys, int clock) 107 - { 108 - return crvml_clocks[crvml_nearest_index(sys, clock)]; 109 - } 110 - 111 - static int crvml_set_clock(struct vml_sys *sys, int clock) 112 - { 113 - void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; 114 - int index; 115 - u32 clock_val; 116 - 117 - index = crvml_nearest_index(sys, clock); 118 - 119 - if (crvml_clocks[index] != clock) 120 - return -EINVAL; 121 - 122 - clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK; 123 - clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT; 124 - iowrite32(clock_val, clock_reg); 125 - ioread32(clock_reg); 126 - 127 - return 0; 128 - } 129 - 130 - static struct vml_sys cr_pll_ops = { 131 - .name = "Carillo Ranch", 132 - .save = crvml_sys_save, 133 - .restore = crvml_sys_restore, 134 - .set_clock = crvml_set_clock, 135 - .nearest_clock = crvml_nearest_clock, 136 - }; 137 - 138 - static int __init cr_pll_init(void) 139 - { 140 - int err; 141 - u32 dev_en; 142 - 143 - mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 144 - CRVML_DEVICE_MCH, NULL); 145 - if (!mch_dev) { 146 - printk(KERN_ERR 147 - "Could not find Carillo Ranch MCH device.\n"); 148 - return -ENODEV; 149 - } 150 - 151 - pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en); 152 - if (!(dev_en & CRVML_MCHEN_BIT)) { 153 - printk(KERN_ERR 154 - "Carillo Ranch MCH device was not enabled.\n"); 155 - pci_dev_put(mch_dev); 156 - return -ENODEV; 157 - } 158 - 159 - pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR, 160 - &mch_bar); 161 - mch_regs_base = 162 - ioremap(mch_bar, CRVML_MCHMAP_SIZE); 163 - if (!mch_regs_base) { 164 - printk(KERN_ERR 165 - "Carillo Ranch MCH device was not enabled.\n"); 166 - pci_dev_put(mch_dev); 167 - return -ENODEV; 168 - } 169 - 170 - err = vmlfb_register_subsys(&cr_pll_ops); 171 - if (err) { 172 - printk(KERN_ERR 173 - "Carillo Ranch failed to initialize vml_sys.\n"); 174 - iounmap(mch_regs_base); 175 - pci_dev_put(mch_dev); 176 - return err; 177 - } 178 - 179 - return 0; 180 - } 181 - 182 - static void __exit cr_pll_exit(void) 183 - { 184 - vmlfb_unregister_subsys(&cr_pll_ops); 185 - 186 - iounmap(mch_regs_base); 187 - pci_dev_put(mch_dev); 188 - } 189 - 190 - module_init(cr_pll_init); 191 - module_exit(cr_pll_exit); 192 - 193 - MODULE_AUTHOR("Tungsten Graphics Inc."); 194 - MODULE_DESCRIPTION("Carillo Ranch PLL Driver"); 195 - MODULE_LICENSE("GPL");
-1175
drivers/video/fbdev/vermilion/vermilion.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (c) Intel Corp. 2007. 4 - * All Rights Reserved. 5 - * 6 - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 7 - * develop this driver. 8 - * 9 - * This file is part of the Vermilion Range fb driver. 10 - * 11 - * Authors: 12 - * Thomas Hellström <thomas-at-tungstengraphics-dot-com> 13 - * Michel Dänzer <michel-at-tungstengraphics-dot-com> 14 - * Alan Hourihane <alanh-at-tungstengraphics-dot-com> 15 - */ 16 - 17 - #include <linux/aperture.h> 18 - #include <linux/module.h> 19 - #include <linux/kernel.h> 20 - #include <linux/errno.h> 21 - #include <linux/string.h> 22 - #include <linux/delay.h> 23 - #include <linux/slab.h> 24 - #include <linux/mm.h> 25 - #include <linux/fb.h> 26 - #include <linux/pci.h> 27 - #include <asm/set_memory.h> 28 - #include <asm/tlbflush.h> 29 - #include <linux/mmzone.h> 30 - 31 - /* #define VERMILION_DEBUG */ 32 - 33 - #include "vermilion.h" 34 - 35 - #define MODULE_NAME "vmlfb" 36 - 37 - #define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) 38 - 39 - static struct mutex vml_mutex; 40 - static struct list_head global_no_mode; 41 - static struct list_head global_has_mode; 42 - static struct fb_ops vmlfb_ops; 43 - static struct vml_sys *subsys = NULL; 44 - static char *vml_default_mode = "1024x768@60"; 45 - static const struct fb_videomode defaultmode = { 46 - NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6, 47 - 0, FB_VMODE_NONINTERLACED 48 - }; 49 - 50 - static u32 vml_mem_requested = (10 * 1024 * 1024); 51 - static u32 vml_mem_contig = (4 * 1024 * 1024); 52 - static u32 vml_mem_min = (4 * 1024 * 1024); 53 - 54 - static u32 vml_clocks[] = { 55 - 6750, 56 - 13500, 57 - 27000, 58 - 29700, 59 - 37125, 60 - 54000, 61 - 59400, 62 - 74250, 63 - 120000, 64 - 148500 65 - }; 66 - 67 - static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks); 68 - 69 - /* 70 - * Allocate a contiguous vram area and make its linear kernel map 71 - * uncached. 72 - */ 73 - 74 - static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order, 75 - unsigned min_order) 76 - { 77 - gfp_t flags; 78 - unsigned long i; 79 - 80 - max_order++; 81 - do { 82 - /* 83 - * Really try hard to get the needed memory. 84 - * We need memory below the first 32MB, so we 85 - * add the __GFP_DMA flag that guarantees that we are 86 - * below the first 16MB. 87 - */ 88 - 89 - flags = __GFP_DMA | __GFP_HIGH | __GFP_KSWAPD_RECLAIM; 90 - va->logical = 91 - __get_free_pages(flags, --max_order); 92 - } while (va->logical == 0 && max_order > min_order); 93 - 94 - if (!va->logical) 95 - return -ENOMEM; 96 - 97 - va->phys = virt_to_phys((void *)va->logical); 98 - va->size = PAGE_SIZE << max_order; 99 - va->order = max_order; 100 - 101 - /* 102 - * It seems like __get_free_pages only ups the usage count 103 - * of the first page. This doesn't work with fault mapping, so 104 - * up the usage count once more (XXX: should use split_page or 105 - * compound page). 106 - */ 107 - 108 - memset((void *)va->logical, 0x00, va->size); 109 - for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) { 110 - get_page(virt_to_page(i)); 111 - } 112 - 113 - /* 114 - * Change caching policy of the linear kernel map to avoid 115 - * mapping type conflicts with user-space mappings. 116 - */ 117 - set_pages_uc(virt_to_page(va->logical), va->size >> PAGE_SHIFT); 118 - 119 - printk(KERN_DEBUG MODULE_NAME 120 - ": Allocated %ld bytes vram area at 0x%08lx\n", 121 - va->size, va->phys); 122 - 123 - return 0; 124 - } 125 - 126 - /* 127 - * Free a contiguous vram area and reset its linear kernel map 128 - * mapping type. 129 - */ 130 - 131 - static void vmlfb_free_vram_area(struct vram_area *va) 132 - { 133 - unsigned long j; 134 - 135 - if (va->logical) { 136 - 137 - /* 138 - * Reset the linear kernel map caching policy. 139 - */ 140 - 141 - set_pages_wb(virt_to_page(va->logical), 142 - va->size >> PAGE_SHIFT); 143 - 144 - /* 145 - * Decrease the usage count on the pages we've used 146 - * to compensate for upping when allocating. 147 - */ 148 - 149 - for (j = va->logical; j < va->logical + va->size; 150 - j += PAGE_SIZE) { 151 - (void)put_page_testzero(virt_to_page(j)); 152 - } 153 - 154 - printk(KERN_DEBUG MODULE_NAME 155 - ": Freeing %ld bytes vram area at 0x%08lx\n", 156 - va->size, va->phys); 157 - free_pages(va->logical, va->order); 158 - 159 - va->logical = 0; 160 - } 161 - } 162 - 163 - /* 164 - * Free allocated vram. 165 - */ 166 - 167 - static void vmlfb_free_vram(struct vml_info *vinfo) 168 - { 169 - int i; 170 - 171 - for (i = 0; i < vinfo->num_areas; ++i) { 172 - vmlfb_free_vram_area(&vinfo->vram[i]); 173 - } 174 - vinfo->num_areas = 0; 175 - } 176 - 177 - /* 178 - * Allocate vram. Currently we try to allocate contiguous areas from the 179 - * __GFP_DMA zone and puzzle them together. A better approach would be to 180 - * allocate one contiguous area for scanout and use one-page allocations for 181 - * offscreen areas. This requires user-space and GPU virtual mappings. 182 - */ 183 - 184 - static int vmlfb_alloc_vram(struct vml_info *vinfo, 185 - size_t requested, 186 - size_t min_total, size_t min_contig) 187 - { 188 - int i, j; 189 - int order; 190 - int contiguous; 191 - int err; 192 - struct vram_area *va; 193 - struct vram_area *va2; 194 - 195 - vinfo->num_areas = 0; 196 - for (i = 0; i < VML_VRAM_AREAS; ++i) { 197 - va = &vinfo->vram[i]; 198 - order = 0; 199 - 200 - while (requested > (PAGE_SIZE << order) && order <= MAX_PAGE_ORDER) 201 - order++; 202 - 203 - err = vmlfb_alloc_vram_area(va, order, 0); 204 - 205 - if (err) 206 - break; 207 - 208 - if (i == 0) { 209 - vinfo->vram_start = va->phys; 210 - vinfo->vram_logical = (void __iomem *) va->logical; 211 - vinfo->vram_contig_size = va->size; 212 - vinfo->num_areas = 1; 213 - } else { 214 - contiguous = 0; 215 - 216 - for (j = 0; j < i; ++j) { 217 - va2 = &vinfo->vram[j]; 218 - if (va->phys + va->size == va2->phys || 219 - va2->phys + va2->size == va->phys) { 220 - contiguous = 1; 221 - break; 222 - } 223 - } 224 - 225 - if (contiguous) { 226 - vinfo->num_areas++; 227 - if (va->phys < vinfo->vram_start) { 228 - vinfo->vram_start = va->phys; 229 - vinfo->vram_logical = 230 - (void __iomem *)va->logical; 231 - } 232 - vinfo->vram_contig_size += va->size; 233 - } else { 234 - vmlfb_free_vram_area(va); 235 - break; 236 - } 237 - } 238 - 239 - if (requested < va->size) 240 - break; 241 - else 242 - requested -= va->size; 243 - } 244 - 245 - if (vinfo->vram_contig_size > min_total && 246 - vinfo->vram_contig_size > min_contig) { 247 - 248 - printk(KERN_DEBUG MODULE_NAME 249 - ": Contiguous vram: %ld bytes at physical 0x%08lx.\n", 250 - (unsigned long)vinfo->vram_contig_size, 251 - (unsigned long)vinfo->vram_start); 252 - 253 - return 0; 254 - } 255 - 256 - printk(KERN_ERR MODULE_NAME 257 - ": Could not allocate requested minimal amount of vram.\n"); 258 - 259 - vmlfb_free_vram(vinfo); 260 - 261 - return -ENOMEM; 262 - } 263 - 264 - /* 265 - * Find the GPU to use with our display controller. 266 - */ 267 - 268 - static int vmlfb_get_gpu(struct vml_par *par) 269 - { 270 - mutex_lock(&vml_mutex); 271 - 272 - par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL); 273 - 274 - if (!par->gpu) { 275 - mutex_unlock(&vml_mutex); 276 - return -ENODEV; 277 - } 278 - 279 - mutex_unlock(&vml_mutex); 280 - 281 - if (pci_enable_device(par->gpu) < 0) { 282 - pci_dev_put(par->gpu); 283 - return -ENODEV; 284 - } 285 - 286 - return 0; 287 - } 288 - 289 - /* 290 - * Find a contiguous vram area that contains a given offset from vram start. 291 - */ 292 - static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset) 293 - { 294 - unsigned long aoffset; 295 - unsigned i; 296 - 297 - for (i = 0; i < vinfo->num_areas; ++i) { 298 - aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start); 299 - 300 - if (aoffset < vinfo->vram[i].size) { 301 - return 0; 302 - } 303 - } 304 - 305 - return -EINVAL; 306 - } 307 - 308 - /* 309 - * Remap the MMIO register spaces of the VDC and the GPU. 310 - */ 311 - 312 - static int vmlfb_enable_mmio(struct vml_par *par) 313 - { 314 - int err; 315 - 316 - par->vdc_mem_base = pci_resource_start(par->vdc, 0); 317 - par->vdc_mem_size = pci_resource_len(par->vdc, 0); 318 - if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) { 319 - printk(KERN_ERR MODULE_NAME 320 - ": Could not claim display controller MMIO.\n"); 321 - return -EBUSY; 322 - } 323 - par->vdc_mem = ioremap(par->vdc_mem_base, par->vdc_mem_size); 324 - if (par->vdc_mem == NULL) { 325 - printk(KERN_ERR MODULE_NAME 326 - ": Could not map display controller MMIO.\n"); 327 - err = -ENOMEM; 328 - goto out_err_0; 329 - } 330 - 331 - par->gpu_mem_base = pci_resource_start(par->gpu, 0); 332 - par->gpu_mem_size = pci_resource_len(par->gpu, 0); 333 - if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) { 334 - printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n"); 335 - err = -EBUSY; 336 - goto out_err_1; 337 - } 338 - par->gpu_mem = ioremap(par->gpu_mem_base, par->gpu_mem_size); 339 - if (par->gpu_mem == NULL) { 340 - printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n"); 341 - err = -ENOMEM; 342 - goto out_err_2; 343 - } 344 - 345 - return 0; 346 - 347 - out_err_2: 348 - release_mem_region(par->gpu_mem_base, par->gpu_mem_size); 349 - out_err_1: 350 - iounmap(par->vdc_mem); 351 - out_err_0: 352 - release_mem_region(par->vdc_mem_base, par->vdc_mem_size); 353 - return err; 354 - } 355 - 356 - /* 357 - * Unmap the VDC and GPU register spaces. 358 - */ 359 - 360 - static void vmlfb_disable_mmio(struct vml_par *par) 361 - { 362 - iounmap(par->gpu_mem); 363 - release_mem_region(par->gpu_mem_base, par->gpu_mem_size); 364 - iounmap(par->vdc_mem); 365 - release_mem_region(par->vdc_mem_base, par->vdc_mem_size); 366 - } 367 - 368 - /* 369 - * Release and uninit the VDC and GPU. 370 - */ 371 - 372 - static void vmlfb_release_devices(struct vml_par *par) 373 - { 374 - if (atomic_dec_and_test(&par->refcount)) { 375 - pci_disable_device(par->gpu); 376 - pci_disable_device(par->vdc); 377 - } 378 - } 379 - 380 - /* 381 - * Free up allocated resources for a device. 382 - */ 383 - 384 - static void vml_pci_remove(struct pci_dev *dev) 385 - { 386 - struct fb_info *info; 387 - struct vml_info *vinfo; 388 - struct vml_par *par; 389 - 390 - info = pci_get_drvdata(dev); 391 - if (info) { 392 - vinfo = container_of(info, struct vml_info, info); 393 - par = vinfo->par; 394 - mutex_lock(&vml_mutex); 395 - unregister_framebuffer(info); 396 - fb_dealloc_cmap(&info->cmap); 397 - vmlfb_free_vram(vinfo); 398 - vmlfb_disable_mmio(par); 399 - vmlfb_release_devices(par); 400 - kfree(vinfo); 401 - kfree(par); 402 - mutex_unlock(&vml_mutex); 403 - } 404 - } 405 - 406 - static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var) 407 - { 408 - switch (var->bits_per_pixel) { 409 - case 16: 410 - var->blue.offset = 0; 411 - var->blue.length = 5; 412 - var->green.offset = 5; 413 - var->green.length = 5; 414 - var->red.offset = 10; 415 - var->red.length = 5; 416 - var->transp.offset = 15; 417 - var->transp.length = 1; 418 - break; 419 - case 32: 420 - var->blue.offset = 0; 421 - var->blue.length = 8; 422 - var->green.offset = 8; 423 - var->green.length = 8; 424 - var->red.offset = 16; 425 - var->red.length = 8; 426 - var->transp.offset = 24; 427 - var->transp.length = 0; 428 - break; 429 - default: 430 - break; 431 - } 432 - 433 - var->blue.msb_right = var->green.msb_right = 434 - var->red.msb_right = var->transp.msb_right = 0; 435 - } 436 - 437 - /* 438 - * Device initialization. 439 - * We initialize one vml_par struct per device and one vml_info 440 - * struct per pipe. Currently we have only one pipe. 441 - */ 442 - 443 - static int vml_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 444 - { 445 - struct vml_info *vinfo; 446 - struct fb_info *info; 447 - struct vml_par *par; 448 - int err; 449 - 450 - err = aperture_remove_conflicting_pci_devices(dev, "vmlfb"); 451 - if (err) 452 - return err; 453 - 454 - par = kzalloc(sizeof(*par), GFP_KERNEL); 455 - if (par == NULL) 456 - return -ENOMEM; 457 - 458 - vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL); 459 - if (vinfo == NULL) { 460 - err = -ENOMEM; 461 - goto out_err_0; 462 - } 463 - 464 - vinfo->par = par; 465 - par->vdc = dev; 466 - atomic_set(&par->refcount, 1); 467 - 468 - switch (id->device) { 469 - case VML_DEVICE_VDC: 470 - if ((err = vmlfb_get_gpu(par))) 471 - goto out_err_1; 472 - pci_set_drvdata(dev, &vinfo->info); 473 - break; 474 - default: 475 - err = -ENODEV; 476 - goto out_err_1; 477 - } 478 - 479 - info = &vinfo->info; 480 - info->flags = FBINFO_PARTIAL_PAN_OK; 481 - 482 - err = vmlfb_enable_mmio(par); 483 - if (err) 484 - goto out_err_2; 485 - 486 - err = vmlfb_alloc_vram(vinfo, vml_mem_requested, 487 - vml_mem_contig, vml_mem_min); 488 - if (err) 489 - goto out_err_3; 490 - 491 - strcpy(info->fix.id, "Vermilion Range"); 492 - info->fix.mmio_start = 0; 493 - info->fix.mmio_len = 0; 494 - info->fix.smem_start = vinfo->vram_start; 495 - info->fix.smem_len = vinfo->vram_contig_size; 496 - info->fix.type = FB_TYPE_PACKED_PIXELS; 497 - info->fix.visual = FB_VISUAL_TRUECOLOR; 498 - info->fix.ypanstep = 1; 499 - info->fix.xpanstep = 1; 500 - info->fix.ywrapstep = 0; 501 - info->fix.accel = FB_ACCEL_NONE; 502 - info->screen_base = vinfo->vram_logical; 503 - info->pseudo_palette = vinfo->pseudo_palette; 504 - info->par = par; 505 - info->fbops = &vmlfb_ops; 506 - info->device = &dev->dev; 507 - 508 - INIT_LIST_HEAD(&vinfo->head); 509 - vinfo->pipe_disabled = 1; 510 - vinfo->cur_blank_mode = FB_BLANK_UNBLANK; 511 - 512 - info->var.grayscale = 0; 513 - info->var.bits_per_pixel = 16; 514 - vmlfb_set_pref_pixel_format(&info->var); 515 - 516 - if (!fb_find_mode 517 - (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) { 518 - printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n"); 519 - } 520 - 521 - if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { 522 - err = -ENOMEM; 523 - goto out_err_4; 524 - } 525 - 526 - err = register_framebuffer(info); 527 - if (err) { 528 - printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n"); 529 - goto out_err_5; 530 - } 531 - 532 - printk("Initialized vmlfb\n"); 533 - 534 - return 0; 535 - 536 - out_err_5: 537 - fb_dealloc_cmap(&info->cmap); 538 - out_err_4: 539 - vmlfb_free_vram(vinfo); 540 - out_err_3: 541 - vmlfb_disable_mmio(par); 542 - out_err_2: 543 - vmlfb_release_devices(par); 544 - out_err_1: 545 - kfree(vinfo); 546 - out_err_0: 547 - kfree(par); 548 - return err; 549 - } 550 - 551 - static int vmlfb_open(struct fb_info *info, int user) 552 - { 553 - /* 554 - * Save registers here? 555 - */ 556 - return 0; 557 - } 558 - 559 - static int vmlfb_release(struct fb_info *info, int user) 560 - { 561 - /* 562 - * Restore registers here. 563 - */ 564 - 565 - return 0; 566 - } 567 - 568 - static int vml_nearest_clock(int clock) 569 - { 570 - 571 - int i; 572 - int cur_index; 573 - int cur_diff; 574 - int diff; 575 - 576 - cur_index = 0; 577 - cur_diff = clock - vml_clocks[0]; 578 - cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; 579 - for (i = 1; i < vml_num_clocks; ++i) { 580 - diff = clock - vml_clocks[i]; 581 - diff = (diff < 0) ? -diff : diff; 582 - if (diff < cur_diff) { 583 - cur_index = i; 584 - cur_diff = diff; 585 - } 586 - } 587 - return vml_clocks[cur_index]; 588 - } 589 - 590 - static int vmlfb_check_var_locked(struct fb_var_screeninfo *var, 591 - struct vml_info *vinfo) 592 - { 593 - u32 pitch; 594 - u64 mem; 595 - int nearest_clock; 596 - int clock; 597 - int clock_diff; 598 - struct fb_var_screeninfo v; 599 - 600 - v = *var; 601 - clock = PICOS2KHZ(var->pixclock); 602 - 603 - if (subsys && subsys->nearest_clock) { 604 - nearest_clock = subsys->nearest_clock(subsys, clock); 605 - } else { 606 - nearest_clock = vml_nearest_clock(clock); 607 - } 608 - 609 - /* 610 - * Accept a 20% diff. 611 - */ 612 - 613 - clock_diff = nearest_clock - clock; 614 - clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff; 615 - if (clock_diff > clock / 5) { 616 - #if 0 617 - printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock); 618 - #endif 619 - return -EINVAL; 620 - } 621 - 622 - v.pixclock = KHZ2PICOS(nearest_clock); 623 - 624 - if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) { 625 - printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n"); 626 - return -EINVAL; 627 - } 628 - if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) { 629 - printk(KERN_DEBUG MODULE_NAME 630 - ": Virtual resolution failure.\n"); 631 - return -EINVAL; 632 - } 633 - switch (v.bits_per_pixel) { 634 - case 0 ... 16: 635 - v.bits_per_pixel = 16; 636 - break; 637 - case 17 ... 32: 638 - v.bits_per_pixel = 32; 639 - break; 640 - default: 641 - printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n", 642 - var->bits_per_pixel); 643 - return -EINVAL; 644 - } 645 - 646 - pitch = ALIGN((var->xres * var->bits_per_pixel) >> 3, 0x40); 647 - mem = (u64)pitch * var->yres_virtual; 648 - if (mem > vinfo->vram_contig_size) { 649 - return -ENOMEM; 650 - } 651 - 652 - switch (v.bits_per_pixel) { 653 - case 16: 654 - if (var->blue.offset != 0 || 655 - var->blue.length != 5 || 656 - var->green.offset != 5 || 657 - var->green.length != 5 || 658 - var->red.offset != 10 || 659 - var->red.length != 5 || 660 - var->transp.offset != 15 || var->transp.length != 1) { 661 - vmlfb_set_pref_pixel_format(&v); 662 - } 663 - break; 664 - case 32: 665 - if (var->blue.offset != 0 || 666 - var->blue.length != 8 || 667 - var->green.offset != 8 || 668 - var->green.length != 8 || 669 - var->red.offset != 16 || 670 - var->red.length != 8 || 671 - (var->transp.length != 0 && var->transp.length != 8) || 672 - (var->transp.length == 8 && var->transp.offset != 24)) { 673 - vmlfb_set_pref_pixel_format(&v); 674 - } 675 - break; 676 - default: 677 - return -EINVAL; 678 - } 679 - 680 - *var = v; 681 - 682 - return 0; 683 - } 684 - 685 - static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 686 - { 687 - struct vml_info *vinfo = container_of(info, struct vml_info, info); 688 - int ret; 689 - 690 - mutex_lock(&vml_mutex); 691 - ret = vmlfb_check_var_locked(var, vinfo); 692 - mutex_unlock(&vml_mutex); 693 - 694 - return ret; 695 - } 696 - 697 - static void vml_wait_vblank(struct vml_info *vinfo) 698 - { 699 - /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ 700 - mdelay(20); 701 - } 702 - 703 - static void vmlfb_disable_pipe(struct vml_info *vinfo) 704 - { 705 - struct vml_par *par = vinfo->par; 706 - 707 - /* Disable the MDVO pad */ 708 - VML_WRITE32(par, VML_RCOMPSTAT, 0); 709 - while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ; 710 - 711 - /* Disable display planes */ 712 - VML_WRITE32(par, VML_DSPCCNTR, 713 - VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE); 714 - (void)VML_READ32(par, VML_DSPCCNTR); 715 - /* Wait for vblank for the disable to take effect */ 716 - vml_wait_vblank(vinfo); 717 - 718 - /* Next, disable display pipes */ 719 - VML_WRITE32(par, VML_PIPEACONF, 0); 720 - (void)VML_READ32(par, VML_PIPEACONF); 721 - 722 - vinfo->pipe_disabled = 1; 723 - } 724 - 725 - #ifdef VERMILION_DEBUG 726 - static void vml_dump_regs(struct vml_info *vinfo) 727 - { 728 - struct vml_par *par = vinfo->par; 729 - 730 - printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n"); 731 - printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A : 0x%08x\n", 732 - (unsigned)VML_READ32(par, VML_HTOTAL_A)); 733 - printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A : 0x%08x\n", 734 - (unsigned)VML_READ32(par, VML_HBLANK_A)); 735 - printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A : 0x%08x\n", 736 - (unsigned)VML_READ32(par, VML_HSYNC_A)); 737 - printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A : 0x%08x\n", 738 - (unsigned)VML_READ32(par, VML_VTOTAL_A)); 739 - printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A : 0x%08x\n", 740 - (unsigned)VML_READ32(par, VML_VBLANK_A)); 741 - printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A : 0x%08x\n", 742 - (unsigned)VML_READ32(par, VML_VSYNC_A)); 743 - printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE : 0x%08x\n", 744 - (unsigned)VML_READ32(par, VML_DSPCSTRIDE)); 745 - printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE : 0x%08x\n", 746 - (unsigned)VML_READ32(par, VML_DSPCSIZE)); 747 - printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS : 0x%08x\n", 748 - (unsigned)VML_READ32(par, VML_DSPCPOS)); 749 - printk(KERN_DEBUG MODULE_NAME ": \tDSPARB : 0x%08x\n", 750 - (unsigned)VML_READ32(par, VML_DSPARB)); 751 - printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR : 0x%08x\n", 752 - (unsigned)VML_READ32(par, VML_DSPCADDR)); 753 - printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A : 0x%08x\n", 754 - (unsigned)VML_READ32(par, VML_BCLRPAT_A)); 755 - printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A : 0x%08x\n", 756 - (unsigned)VML_READ32(par, VML_CANVSCLR_A)); 757 - printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC : 0x%08x\n", 758 - (unsigned)VML_READ32(par, VML_PIPEASRC)); 759 - printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF : 0x%08x\n", 760 - (unsigned)VML_READ32(par, VML_PIPEACONF)); 761 - printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR : 0x%08x\n", 762 - (unsigned)VML_READ32(par, VML_DSPCCNTR)); 763 - printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT : 0x%08x\n", 764 - (unsigned)VML_READ32(par, VML_RCOMPSTAT)); 765 - printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n"); 766 - } 767 - #endif 768 - 769 - static int vmlfb_set_par_locked(struct vml_info *vinfo) 770 - { 771 - struct vml_par *par = vinfo->par; 772 - struct fb_info *info = &vinfo->info; 773 - struct fb_var_screeninfo *var = &info->var; 774 - u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end; 775 - u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end; 776 - u32 dspcntr; 777 - int clock; 778 - 779 - vinfo->bytes_per_pixel = var->bits_per_pixel >> 3; 780 - vinfo->stride = ALIGN(var->xres_virtual * vinfo->bytes_per_pixel, 0x40); 781 - info->fix.line_length = vinfo->stride; 782 - 783 - if (!subsys) 784 - return 0; 785 - 786 - htotal = 787 - var->xres + var->right_margin + var->hsync_len + var->left_margin; 788 - hactive = var->xres; 789 - hblank_start = var->xres; 790 - hblank_end = htotal; 791 - hsync_start = hactive + var->right_margin; 792 - hsync_end = hsync_start + var->hsync_len; 793 - 794 - vtotal = 795 - var->yres + var->lower_margin + var->vsync_len + var->upper_margin; 796 - vactive = var->yres; 797 - vblank_start = var->yres; 798 - vblank_end = vtotal; 799 - vsync_start = vactive + var->lower_margin; 800 - vsync_end = vsync_start + var->vsync_len; 801 - 802 - dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS; 803 - clock = PICOS2KHZ(var->pixclock); 804 - 805 - if (subsys->nearest_clock) { 806 - clock = subsys->nearest_clock(subsys, clock); 807 - } else { 808 - clock = vml_nearest_clock(clock); 809 - } 810 - printk(KERN_DEBUG MODULE_NAME 811 - ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal, 812 - ((clock / htotal) * 1000) / vtotal); 813 - 814 - switch (var->bits_per_pixel) { 815 - case 16: 816 - dspcntr |= VML_GFX_ARGB1555; 817 - break; 818 - case 32: 819 - if (var->transp.length == 8) 820 - dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT; 821 - else 822 - dspcntr |= VML_GFX_RGB0888; 823 - break; 824 - default: 825 - return -EINVAL; 826 - } 827 - 828 - vmlfb_disable_pipe(vinfo); 829 - mb(); 830 - 831 - if (subsys->set_clock) 832 - subsys->set_clock(subsys, clock); 833 - else 834 - return -EINVAL; 835 - 836 - VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1)); 837 - VML_WRITE32(par, VML_HBLANK_A, 838 - ((hblank_end - 1) << 16) | (hblank_start - 1)); 839 - VML_WRITE32(par, VML_HSYNC_A, 840 - ((hsync_end - 1) << 16) | (hsync_start - 1)); 841 - VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1)); 842 - VML_WRITE32(par, VML_VBLANK_A, 843 - ((vblank_end - 1) << 16) | (vblank_start - 1)); 844 - VML_WRITE32(par, VML_VSYNC_A, 845 - ((vsync_end - 1) << 16) | (vsync_start - 1)); 846 - VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride); 847 - VML_WRITE32(par, VML_DSPCSIZE, 848 - ((var->yres - 1) << 16) | (var->xres - 1)); 849 - VML_WRITE32(par, VML_DSPCPOS, 0x00000000); 850 - VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT); 851 - VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000); 852 - VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000); 853 - VML_WRITE32(par, VML_PIPEASRC, 854 - ((var->xres - 1) << 16) | (var->yres - 1)); 855 - 856 - wmb(); 857 - VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE); 858 - wmb(); 859 - VML_WRITE32(par, VML_DSPCCNTR, dspcntr); 860 - wmb(); 861 - VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + 862 - var->yoffset * vinfo->stride + 863 - var->xoffset * vinfo->bytes_per_pixel); 864 - 865 - VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE); 866 - 867 - while (!(VML_READ32(par, VML_RCOMPSTAT) & 868 - (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ; 869 - 870 - vinfo->pipe_disabled = 0; 871 - #ifdef VERMILION_DEBUG 872 - vml_dump_regs(vinfo); 873 - #endif 874 - 875 - return 0; 876 - } 877 - 878 - static int vmlfb_set_par(struct fb_info *info) 879 - { 880 - struct vml_info *vinfo = container_of(info, struct vml_info, info); 881 - int ret; 882 - 883 - mutex_lock(&vml_mutex); 884 - list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode); 885 - ret = vmlfb_set_par_locked(vinfo); 886 - 887 - mutex_unlock(&vml_mutex); 888 - return ret; 889 - } 890 - 891 - static int vmlfb_blank_locked(struct vml_info *vinfo) 892 - { 893 - struct vml_par *par = vinfo->par; 894 - u32 cur = VML_READ32(par, VML_PIPEACONF); 895 - 896 - switch (vinfo->cur_blank_mode) { 897 - case FB_BLANK_UNBLANK: 898 - if (vinfo->pipe_disabled) { 899 - vmlfb_set_par_locked(vinfo); 900 - } 901 - VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER); 902 - (void)VML_READ32(par, VML_PIPEACONF); 903 - break; 904 - case FB_BLANK_NORMAL: 905 - if (vinfo->pipe_disabled) { 906 - vmlfb_set_par_locked(vinfo); 907 - } 908 - VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER); 909 - (void)VML_READ32(par, VML_PIPEACONF); 910 - break; 911 - case FB_BLANK_VSYNC_SUSPEND: 912 - case FB_BLANK_HSYNC_SUSPEND: 913 - if (!vinfo->pipe_disabled) { 914 - vmlfb_disable_pipe(vinfo); 915 - } 916 - break; 917 - case FB_BLANK_POWERDOWN: 918 - if (!vinfo->pipe_disabled) { 919 - vmlfb_disable_pipe(vinfo); 920 - } 921 - break; 922 - default: 923 - return -EINVAL; 924 - } 925 - 926 - return 0; 927 - } 928 - 929 - static int vmlfb_blank(int blank_mode, struct fb_info *info) 930 - { 931 - struct vml_info *vinfo = container_of(info, struct vml_info, info); 932 - int ret; 933 - 934 - mutex_lock(&vml_mutex); 935 - vinfo->cur_blank_mode = blank_mode; 936 - ret = vmlfb_blank_locked(vinfo); 937 - mutex_unlock(&vml_mutex); 938 - return ret; 939 - } 940 - 941 - static int vmlfb_pan_display(struct fb_var_screeninfo *var, 942 - struct fb_info *info) 943 - { 944 - struct vml_info *vinfo = container_of(info, struct vml_info, info); 945 - struct vml_par *par = vinfo->par; 946 - 947 - mutex_lock(&vml_mutex); 948 - VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + 949 - var->yoffset * vinfo->stride + 950 - var->xoffset * vinfo->bytes_per_pixel); 951 - (void)VML_READ32(par, VML_DSPCADDR); 952 - mutex_unlock(&vml_mutex); 953 - 954 - return 0; 955 - } 956 - 957 - static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 958 - u_int transp, struct fb_info *info) 959 - { 960 - u32 v; 961 - 962 - if (regno >= 16) 963 - return -EINVAL; 964 - 965 - if (info->var.grayscale) { 966 - red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 967 - } 968 - 969 - if (info->fix.visual != FB_VISUAL_TRUECOLOR) 970 - return -EINVAL; 971 - 972 - red = VML_TOHW(red, info->var.red.length); 973 - blue = VML_TOHW(blue, info->var.blue.length); 974 - green = VML_TOHW(green, info->var.green.length); 975 - transp = VML_TOHW(transp, info->var.transp.length); 976 - 977 - v = (red << info->var.red.offset) | 978 - (green << info->var.green.offset) | 979 - (blue << info->var.blue.offset) | 980 - (transp << info->var.transp.offset); 981 - 982 - switch (info->var.bits_per_pixel) { 983 - case 16: 984 - ((u32 *) info->pseudo_palette)[regno] = v; 985 - break; 986 - case 24: 987 - case 32: 988 - ((u32 *) info->pseudo_palette)[regno] = v; 989 - break; 990 - } 991 - return 0; 992 - } 993 - 994 - static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) 995 - { 996 - struct vml_info *vinfo = container_of(info, struct vml_info, info); 997 - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 998 - int ret; 999 - unsigned long prot; 1000 - 1001 - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); 1002 - 1003 - ret = vmlfb_vram_offset(vinfo, offset); 1004 - if (ret) 1005 - return -EINVAL; 1006 - 1007 - prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK; 1008 - pgprot_val(vma->vm_page_prot) = 1009 - prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS); 1010 - 1011 - return vm_iomap_memory(vma, vinfo->vram_start, 1012 - vinfo->vram_contig_size); 1013 - } 1014 - 1015 - static int vmlfb_sync(struct fb_info *info) 1016 - { 1017 - return 0; 1018 - } 1019 - 1020 - static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1021 - { 1022 - return -EINVAL; /* just to force soft_cursor() call */ 1023 - } 1024 - 1025 - static struct fb_ops vmlfb_ops = { 1026 - .owner = THIS_MODULE, 1027 - .fb_open = vmlfb_open, 1028 - .fb_release = vmlfb_release, 1029 - __FB_DEFAULT_IOMEM_OPS_RDWR, 1030 - .fb_check_var = vmlfb_check_var, 1031 - .fb_set_par = vmlfb_set_par, 1032 - .fb_blank = vmlfb_blank, 1033 - .fb_pan_display = vmlfb_pan_display, 1034 - __FB_DEFAULT_IOMEM_OPS_DRAW, 1035 - .fb_cursor = vmlfb_cursor, 1036 - .fb_sync = vmlfb_sync, 1037 - .fb_mmap = vmlfb_mmap, 1038 - .fb_setcolreg = vmlfb_setcolreg 1039 - }; 1040 - 1041 - static const struct pci_device_id vml_ids[] = { 1042 - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)}, 1043 - {0} 1044 - }; 1045 - 1046 - static struct pci_driver vmlfb_pci_driver = { 1047 - .name = "vmlfb", 1048 - .id_table = vml_ids, 1049 - .probe = vml_pci_probe, 1050 - .remove = vml_pci_remove, 1051 - }; 1052 - 1053 - static void __exit vmlfb_cleanup(void) 1054 - { 1055 - pci_unregister_driver(&vmlfb_pci_driver); 1056 - } 1057 - 1058 - static int __init vmlfb_init(void) 1059 - { 1060 - 1061 - #ifndef MODULE 1062 - char *option = NULL; 1063 - #endif 1064 - 1065 - if (fb_modesetting_disabled("vmlfb")) 1066 - return -ENODEV; 1067 - 1068 - #ifndef MODULE 1069 - if (fb_get_options(MODULE_NAME, &option)) 1070 - return -ENODEV; 1071 - #endif 1072 - 1073 - printk(KERN_DEBUG MODULE_NAME ": initializing\n"); 1074 - mutex_init(&vml_mutex); 1075 - INIT_LIST_HEAD(&global_no_mode); 1076 - INIT_LIST_HEAD(&global_has_mode); 1077 - 1078 - return pci_register_driver(&vmlfb_pci_driver); 1079 - } 1080 - 1081 - int vmlfb_register_subsys(struct vml_sys *sys) 1082 - { 1083 - struct vml_info *entry; 1084 - struct list_head *list; 1085 - u32 save_activate; 1086 - 1087 - mutex_lock(&vml_mutex); 1088 - if (subsys != NULL) { 1089 - subsys->restore(subsys); 1090 - } 1091 - subsys = sys; 1092 - subsys->save(subsys); 1093 - 1094 - /* 1095 - * We need to restart list traversal for each item, since we 1096 - * release the list mutex in the loop. 1097 - */ 1098 - 1099 - list = global_no_mode.next; 1100 - while (list != &global_no_mode) { 1101 - list_del_init(list); 1102 - entry = list_entry(list, struct vml_info, head); 1103 - 1104 - /* 1105 - * First, try the current mode which might not be 1106 - * completely validated with respect to the pixel clock. 1107 - */ 1108 - 1109 - if (!vmlfb_check_var_locked(&entry->info.var, entry)) { 1110 - vmlfb_set_par_locked(entry); 1111 - list_add_tail(list, &global_has_mode); 1112 - } else { 1113 - 1114 - /* 1115 - * Didn't work. Try to find another mode, 1116 - * that matches this subsys. 1117 - */ 1118 - 1119 - mutex_unlock(&vml_mutex); 1120 - save_activate = entry->info.var.activate; 1121 - entry->info.var.bits_per_pixel = 16; 1122 - vmlfb_set_pref_pixel_format(&entry->info.var); 1123 - if (fb_find_mode(&entry->info.var, 1124 - &entry->info, 1125 - vml_default_mode, NULL, 0, NULL, 16)) { 1126 - entry->info.var.activate |= 1127 - FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; 1128 - fb_set_var(&entry->info, &entry->info.var); 1129 - } else { 1130 - printk(KERN_ERR MODULE_NAME 1131 - ": Sorry. no mode found for this subsys.\n"); 1132 - } 1133 - entry->info.var.activate = save_activate; 1134 - mutex_lock(&vml_mutex); 1135 - } 1136 - vmlfb_blank_locked(entry); 1137 - list = global_no_mode.next; 1138 - } 1139 - mutex_unlock(&vml_mutex); 1140 - 1141 - printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n", 1142 - subsys->name ? subsys->name : "unknown"); 1143 - return 0; 1144 - } 1145 - 1146 - EXPORT_SYMBOL_GPL(vmlfb_register_subsys); 1147 - 1148 - void vmlfb_unregister_subsys(struct vml_sys *sys) 1149 - { 1150 - struct vml_info *entry, *next; 1151 - 1152 - mutex_lock(&vml_mutex); 1153 - if (subsys != sys) { 1154 - mutex_unlock(&vml_mutex); 1155 - return; 1156 - } 1157 - subsys->restore(subsys); 1158 - subsys = NULL; 1159 - list_for_each_entry_safe(entry, next, &global_has_mode, head) { 1160 - printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n"); 1161 - vmlfb_disable_pipe(entry); 1162 - list_move_tail(&entry->head, &global_no_mode); 1163 - } 1164 - mutex_unlock(&vml_mutex); 1165 - } 1166 - 1167 - EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys); 1168 - 1169 - module_init(vmlfb_init); 1170 - module_exit(vmlfb_cleanup); 1171 - 1172 - MODULE_AUTHOR("Tungsten Graphics"); 1173 - MODULE_DESCRIPTION("Initialization of the Vermilion display devices"); 1174 - MODULE_VERSION("1.0.0"); 1175 - MODULE_LICENSE("GPL");
-245
drivers/video/fbdev/vermilion/vermilion.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - /* 3 - * Copyright (c) Intel Corp. 2007. 4 - * All Rights Reserved. 5 - * 6 - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 7 - * develop this driver. 8 - * 9 - * This file is part of the Vermilion Range fb driver. 10 - * 11 - * Authors: 12 - * Thomas Hellström <thomas-at-tungstengraphics-dot-com> 13 - */ 14 - 15 - #ifndef _VERMILION_H_ 16 - #define _VERMILION_H_ 17 - 18 - #include <linux/kernel.h> 19 - #include <linux/pci.h> 20 - #include <linux/atomic.h> 21 - #include <linux/mutex.h> 22 - 23 - #define VML_DEVICE_GPU 0x5002 24 - #define VML_DEVICE_VDC 0x5009 25 - 26 - #define VML_VRAM_AREAS 3 27 - #define VML_MAX_XRES 1024 28 - #define VML_MAX_YRES 768 29 - #define VML_MAX_XRES_VIRTUAL 1040 30 - 31 - /* 32 - * Display controller registers: 33 - */ 34 - 35 - /* Display controller 10-bit color representation */ 36 - 37 - #define VML_R_MASK 0x3FF00000 38 - #define VML_R_SHIFT 20 39 - #define VML_G_MASK 0x000FFC00 40 - #define VML_G_SHIFT 10 41 - #define VML_B_MASK 0x000003FF 42 - #define VML_B_SHIFT 0 43 - 44 - /* Graphics plane control */ 45 - #define VML_DSPCCNTR 0x00072180 46 - #define VML_GFX_ENABLE 0x80000000 47 - #define VML_GFX_GAMMABYPASS 0x40000000 48 - #define VML_GFX_ARGB1555 0x0C000000 49 - #define VML_GFX_RGB0888 0x18000000 50 - #define VML_GFX_ARGB8888 0x1C000000 51 - #define VML_GFX_ALPHACONST 0x02000000 52 - #define VML_GFX_ALPHAMULT 0x01000000 53 - #define VML_GFX_CONST_ALPHA 0x000000FF 54 - 55 - /* Graphics plane start address. Pixel aligned. */ 56 - #define VML_DSPCADDR 0x00072184 57 - 58 - /* Graphics plane stride register. */ 59 - #define VML_DSPCSTRIDE 0x00072188 60 - 61 - /* Graphics plane position register. */ 62 - #define VML_DSPCPOS 0x0007218C 63 - #define VML_POS_YMASK 0x0FFF0000 64 - #define VML_POS_YSHIFT 16 65 - #define VML_POS_XMASK 0x00000FFF 66 - #define VML_POS_XSHIFT 0 67 - 68 - /* Graphics plane height and width */ 69 - #define VML_DSPCSIZE 0x00072190 70 - #define VML_SIZE_HMASK 0x0FFF0000 71 - #define VML_SIZE_HSHIFT 16 72 - #define VML_SISE_WMASK 0x00000FFF 73 - #define VML_SIZE_WSHIFT 0 74 - 75 - /* Graphics plane gamma correction lookup table registers (129 * 32 bits) */ 76 - #define VML_DSPCGAMLUT 0x00072200 77 - 78 - /* Pixel video output configuration register */ 79 - #define VML_PVOCONFIG 0x00061140 80 - #define VML_CONFIG_BASE 0x80000000 81 - #define VML_CONFIG_PIXEL_SWAP 0x04000000 82 - #define VML_CONFIG_DE_INV 0x01000000 83 - #define VML_CONFIG_HREF_INV 0x00400000 84 - #define VML_CONFIG_VREF_INV 0x00100000 85 - #define VML_CONFIG_CLK_INV 0x00040000 86 - #define VML_CONFIG_CLK_DIV2 0x00010000 87 - #define VML_CONFIG_ESTRB_INV 0x00008000 88 - 89 - /* Pipe A Horizontal total register */ 90 - #define VML_HTOTAL_A 0x00060000 91 - #define VML_HTOTAL_MASK 0x1FFF0000 92 - #define VML_HTOTAL_SHIFT 16 93 - #define VML_HTOTAL_VAL 8192 94 - #define VML_HACTIVE_MASK 0x000007FF 95 - #define VML_HACTIVE_SHIFT 0 96 - #define VML_HACTIVE_VAL 4096 97 - 98 - /* Pipe A Horizontal Blank register */ 99 - #define VML_HBLANK_A 0x00060004 100 - #define VML_HBLANK_END_MASK 0x1FFF0000 101 - #define VML_HBLANK_END_SHIFT 16 102 - #define VML_HBLANK_END_VAL 8192 103 - #define VML_HBLANK_START_MASK 0x00001FFF 104 - #define VML_HBLANK_START_SHIFT 0 105 - #define VML_HBLANK_START_VAL 8192 106 - 107 - /* Pipe A Horizontal Sync register */ 108 - #define VML_HSYNC_A 0x00060008 109 - #define VML_HSYNC_END_MASK 0x1FFF0000 110 - #define VML_HSYNC_END_SHIFT 16 111 - #define VML_HSYNC_END_VAL 8192 112 - #define VML_HSYNC_START_MASK 0x00001FFF 113 - #define VML_HSYNC_START_SHIFT 0 114 - #define VML_HSYNC_START_VAL 8192 115 - 116 - /* Pipe A Vertical total register */ 117 - #define VML_VTOTAL_A 0x0006000C 118 - #define VML_VTOTAL_MASK 0x1FFF0000 119 - #define VML_VTOTAL_SHIFT 16 120 - #define VML_VTOTAL_VAL 8192 121 - #define VML_VACTIVE_MASK 0x000007FF 122 - #define VML_VACTIVE_SHIFT 0 123 - #define VML_VACTIVE_VAL 4096 124 - 125 - /* Pipe A Vertical Blank register */ 126 - #define VML_VBLANK_A 0x00060010 127 - #define VML_VBLANK_END_MASK 0x1FFF0000 128 - #define VML_VBLANK_END_SHIFT 16 129 - #define VML_VBLANK_END_VAL 8192 130 - #define VML_VBLANK_START_MASK 0x00001FFF 131 - #define VML_VBLANK_START_SHIFT 0 132 - #define VML_VBLANK_START_VAL 8192 133 - 134 - /* Pipe A Vertical Sync register */ 135 - #define VML_VSYNC_A 0x00060014 136 - #define VML_VSYNC_END_MASK 0x1FFF0000 137 - #define VML_VSYNC_END_SHIFT 16 138 - #define VML_VSYNC_END_VAL 8192 139 - #define VML_VSYNC_START_MASK 0x00001FFF 140 - #define VML_VSYNC_START_SHIFT 0 141 - #define VML_VSYNC_START_VAL 8192 142 - 143 - /* Pipe A Source Image size (minus one - equal to active size) 144 - * Programmable while pipe is enabled. 145 - */ 146 - #define VML_PIPEASRC 0x0006001C 147 - #define VML_PIPEASRC_HMASK 0x0FFF0000 148 - #define VML_PIPEASRC_HSHIFT 16 149 - #define VML_PIPEASRC_VMASK 0x00000FFF 150 - #define VML_PIPEASRC_VSHIFT 0 151 - 152 - /* Pipe A Border Color Pattern register (10 bit color) */ 153 - #define VML_BCLRPAT_A 0x00060020 154 - 155 - /* Pipe A Canvas Color register (10 bit color) */ 156 - #define VML_CANVSCLR_A 0x00060024 157 - 158 - /* Pipe A Configuration register */ 159 - #define VML_PIPEACONF 0x00070008 160 - #define VML_PIPE_BASE 0x00000000 161 - #define VML_PIPE_ENABLE 0x80000000 162 - #define VML_PIPE_FORCE_BORDER 0x02000000 163 - #define VML_PIPE_PLANES_OFF 0x00080000 164 - #define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000 165 - 166 - /* Pipe A FIFO setting */ 167 - #define VML_DSPARB 0x00070030 168 - #define VML_FIFO_DEFAULT 0x00001D9C 169 - 170 - /* MDVO rcomp status & pads control register */ 171 - #define VML_RCOMPSTAT 0x00070048 172 - #define VML_MDVO_VDC_I_RCOMP 0x80000000 173 - #define VML_MDVO_POWERSAVE_OFF 0x00000008 174 - #define VML_MDVO_PAD_ENABLE 0x00000004 175 - #define VML_MDVO_PULLDOWN_ENABLE 0x00000001 176 - 177 - struct vml_par { 178 - struct pci_dev *vdc; 179 - u64 vdc_mem_base; 180 - u64 vdc_mem_size; 181 - char __iomem *vdc_mem; 182 - 183 - struct pci_dev *gpu; 184 - u64 gpu_mem_base; 185 - u64 gpu_mem_size; 186 - char __iomem *gpu_mem; 187 - 188 - atomic_t refcount; 189 - }; 190 - 191 - struct vram_area { 192 - unsigned long logical; 193 - unsigned long phys; 194 - unsigned long size; 195 - unsigned order; 196 - }; 197 - 198 - struct vml_info { 199 - struct fb_info info; 200 - struct vml_par *par; 201 - struct list_head head; 202 - struct vram_area vram[VML_VRAM_AREAS]; 203 - u64 vram_start; 204 - u64 vram_contig_size; 205 - u32 num_areas; 206 - void __iomem *vram_logical; 207 - u32 pseudo_palette[16]; 208 - u32 stride; 209 - u32 bytes_per_pixel; 210 - atomic_t vmas; 211 - int cur_blank_mode; 212 - int pipe_disabled; 213 - }; 214 - 215 - /* 216 - * Subsystem 217 - */ 218 - 219 - struct vml_sys { 220 - char *name; 221 - 222 - /* 223 - * Save / Restore; 224 - */ 225 - 226 - int (*save) (struct vml_sys * sys); 227 - int (*restore) (struct vml_sys * sys); 228 - 229 - /* 230 - * PLL programming; 231 - */ 232 - 233 - int (*set_clock) (struct vml_sys * sys, int clock); 234 - int (*nearest_clock) (const struct vml_sys * sys, int clock); 235 - }; 236 - 237 - extern int vmlfb_register_subsys(struct vml_sys *sys); 238 - extern void vmlfb_unregister_subsys(struct vml_sys *sys); 239 - 240 - #define VML_READ32(_par, _offset) \ 241 - (ioread32((_par)->vdc_mem + (_offset))) 242 - #define VML_WRITE32(_par, _offset, _value) \ 243 - iowrite32(_value, (_par)->vdc_mem + (_offset)) 244 - 245 - #endif
+3 -3
drivers/video/logo/pnmtologo.c
··· 249 249 fputs("\n};\n\n", out); 250 250 fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname); 251 251 fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]); 252 - fprintf(out, "\t.width\t\t= %d,\n", logo_width); 253 - fprintf(out, "\t.height\t\t= %d,\n", logo_height); 252 + fprintf(out, "\t.width\t\t= %u,\n", logo_width); 253 + fprintf(out, "\t.height\t\t= %u,\n", logo_height); 254 254 if (logo_type == LINUX_LOGO_CLUT224) { 255 - fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize); 255 + fprintf(out, "\t.clutsize\t= %u,\n", logo_clutsize); 256 256 fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname); 257 257 } 258 258 fprintf(out, "\t.data\t\t= %s_data\n", logoname);
+5
drivers/video/sticore.c
··· 1041 1041 1042 1042 print_pa_hwpath(dev, sti->pa_path); 1043 1043 sticore_check_for_default_sti(sti, sti->pa_path); 1044 + 1045 + sti->dev = &dev->dev; 1046 + 1044 1047 return 0; 1045 1048 } 1046 1049 ··· 1087 1084 pr_warn("Unable to handle STI device '%s'\n", pci_name(pd)); 1088 1085 return -ENODEV; 1089 1086 } 1087 + 1088 + sti->dev = &pd->dev; 1090 1089 #endif /* CONFIG_PCI */ 1091 1090 1092 1091 return 0;
-87
include/linux/amba/clcd-regs.h
··· 1 - /* 2 - * David A Rusling 3 - * 4 - * Copyright (C) 2001 ARM Limited 5 - * 6 - * This file is subject to the terms and conditions of the GNU General Public 7 - * License. See the file COPYING in the main directory of this archive 8 - * for more details. 9 - */ 10 - 11 - #ifndef AMBA_CLCD_REGS_H 12 - #define AMBA_CLCD_REGS_H 13 - 14 - /* 15 - * CLCD Controller Internal Register addresses 16 - */ 17 - #define CLCD_TIM0 0x00000000 18 - #define CLCD_TIM1 0x00000004 19 - #define CLCD_TIM2 0x00000008 20 - #define CLCD_TIM3 0x0000000c 21 - #define CLCD_UBAS 0x00000010 22 - #define CLCD_LBAS 0x00000014 23 - 24 - #define CLCD_PL110_IENB 0x00000018 25 - #define CLCD_PL110_CNTL 0x0000001c 26 - #define CLCD_PL110_STAT 0x00000020 27 - #define CLCD_PL110_INTR 0x00000024 28 - #define CLCD_PL110_UCUR 0x00000028 29 - #define CLCD_PL110_LCUR 0x0000002C 30 - 31 - #define CLCD_PL111_CNTL 0x00000018 32 - #define CLCD_PL111_IENB 0x0000001c 33 - #define CLCD_PL111_RIS 0x00000020 34 - #define CLCD_PL111_MIS 0x00000024 35 - #define CLCD_PL111_ICR 0x00000028 36 - #define CLCD_PL111_UCUR 0x0000002c 37 - #define CLCD_PL111_LCUR 0x00000030 38 - 39 - #define CLCD_PALL 0x00000200 40 - #define CLCD_PALETTE 0x00000200 41 - 42 - #define TIM2_PCD_LO_MASK GENMASK(4, 0) 43 - #define TIM2_PCD_LO_BITS 5 44 - #define TIM2_CLKSEL (1 << 5) 45 - #define TIM2_ACB_MASK GENMASK(10, 6) 46 - #define TIM2_IVS (1 << 11) 47 - #define TIM2_IHS (1 << 12) 48 - #define TIM2_IPC (1 << 13) 49 - #define TIM2_IOE (1 << 14) 50 - #define TIM2_BCD (1 << 26) 51 - #define TIM2_PCD_HI_MASK GENMASK(31, 27) 52 - #define TIM2_PCD_HI_BITS 5 53 - #define TIM2_PCD_HI_SHIFT 27 54 - 55 - #define CNTL_LCDEN (1 << 0) 56 - #define CNTL_LCDBPP1 (0 << 1) 57 - #define CNTL_LCDBPP2 (1 << 1) 58 - #define CNTL_LCDBPP4 (2 << 1) 59 - #define CNTL_LCDBPP8 (3 << 1) 60 - #define CNTL_LCDBPP16 (4 << 1) 61 - #define CNTL_LCDBPP16_565 (6 << 1) 62 - #define CNTL_LCDBPP16_444 (7 << 1) 63 - #define CNTL_LCDBPP24 (5 << 1) 64 - #define CNTL_LCDBW (1 << 4) 65 - #define CNTL_LCDTFT (1 << 5) 66 - #define CNTL_LCDMONO8 (1 << 6) 67 - #define CNTL_LCDDUAL (1 << 7) 68 - #define CNTL_BGR (1 << 8) 69 - #define CNTL_BEBO (1 << 9) 70 - #define CNTL_BEPO (1 << 10) 71 - #define CNTL_LCDPWR (1 << 11) 72 - #define CNTL_LCDVCOMP(x) ((x) << 12) 73 - #define CNTL_LDMAFIFOTIME (1 << 15) 74 - #define CNTL_WATERMARK (1 << 16) 75 - 76 - /* ST Microelectronics variant bits */ 77 - #define CNTL_ST_1XBPP_444 0x0 78 - #define CNTL_ST_1XBPP_5551 (1 << 17) 79 - #define CNTL_ST_1XBPP_565 (1 << 18) 80 - #define CNTL_ST_CDWID_12 0x0 81 - #define CNTL_ST_CDWID_16 (1 << 19) 82 - #define CNTL_ST_CDWID_18 (1 << 20) 83 - #define CNTL_ST_CDWID_24 ((1 << 19)|(1 << 20)) 84 - #define CNTL_ST_CEAEN (1 << 21) 85 - #define CNTL_ST_LCDBPP24_PACKED (6 << 1) 86 - 87 - #endif /* AMBA_CLCD_REGS_H */
-290
include/linux/amba/clcd.h
··· 1 - /* 2 - * linux/include/asm-arm/hardware/amba_clcd.h -- Integrator LCD panel. 3 - * 4 - * David A Rusling 5 - * 6 - * Copyright (C) 2001 ARM Limited 7 - * 8 - * This file is subject to the terms and conditions of the GNU General Public 9 - * License. See the file COPYING in the main directory of this archive 10 - * for more details. 11 - */ 12 - #include <linux/fb.h> 13 - #include <linux/amba/clcd-regs.h> 14 - 15 - enum { 16 - /* individual formats */ 17 - CLCD_CAP_RGB444 = (1 << 0), 18 - CLCD_CAP_RGB5551 = (1 << 1), 19 - CLCD_CAP_RGB565 = (1 << 2), 20 - CLCD_CAP_RGB888 = (1 << 3), 21 - CLCD_CAP_BGR444 = (1 << 4), 22 - CLCD_CAP_BGR5551 = (1 << 5), 23 - CLCD_CAP_BGR565 = (1 << 6), 24 - CLCD_CAP_BGR888 = (1 << 7), 25 - 26 - /* connection layouts */ 27 - CLCD_CAP_444 = CLCD_CAP_RGB444 | CLCD_CAP_BGR444, 28 - CLCD_CAP_5551 = CLCD_CAP_RGB5551 | CLCD_CAP_BGR5551, 29 - CLCD_CAP_565 = CLCD_CAP_RGB565 | CLCD_CAP_BGR565, 30 - CLCD_CAP_888 = CLCD_CAP_RGB888 | CLCD_CAP_BGR888, 31 - 32 - /* red/blue ordering */ 33 - CLCD_CAP_RGB = CLCD_CAP_RGB444 | CLCD_CAP_RGB5551 | 34 - CLCD_CAP_RGB565 | CLCD_CAP_RGB888, 35 - CLCD_CAP_BGR = CLCD_CAP_BGR444 | CLCD_CAP_BGR5551 | 36 - CLCD_CAP_BGR565 | CLCD_CAP_BGR888, 37 - 38 - CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB, 39 - }; 40 - 41 - struct backlight_device; 42 - 43 - struct clcd_panel { 44 - struct fb_videomode mode; 45 - signed short width; /* width in mm */ 46 - signed short height; /* height in mm */ 47 - u32 tim2; 48 - u32 tim3; 49 - u32 cntl; 50 - u32 caps; 51 - unsigned int bpp:8, 52 - fixedtimings:1, 53 - grayscale:1; 54 - unsigned int connector; 55 - struct backlight_device *backlight; 56 - /* 57 - * If the B/R lines are switched between the CLCD 58 - * and the panel we need to know this and not try to 59 - * compensate with the BGR bit in the control register. 60 - */ 61 - bool bgr_connection; 62 - }; 63 - 64 - struct clcd_regs { 65 - u32 tim0; 66 - u32 tim1; 67 - u32 tim2; 68 - u32 tim3; 69 - u32 cntl; 70 - unsigned long pixclock; 71 - }; 72 - 73 - struct clcd_fb; 74 - 75 - /* 76 - * the board-type specific routines 77 - */ 78 - struct clcd_board { 79 - const char *name; 80 - 81 - /* 82 - * Optional. Hardware capability flags. 83 - */ 84 - u32 caps; 85 - 86 - /* 87 - * Optional. Check whether the var structure is acceptable 88 - * for this display. 89 - */ 90 - int (*check)(struct clcd_fb *fb, struct fb_var_screeninfo *var); 91 - 92 - /* 93 - * Compulsory. Decode fb->fb.var into regs->*. In the case of 94 - * fixed timing, set regs->* to the register values required. 95 - */ 96 - void (*decode)(struct clcd_fb *fb, struct clcd_regs *regs); 97 - 98 - /* 99 - * Optional. Disable any extra display hardware. 100 - */ 101 - void (*disable)(struct clcd_fb *); 102 - 103 - /* 104 - * Optional. Enable any extra display hardware. 105 - */ 106 - void (*enable)(struct clcd_fb *); 107 - 108 - /* 109 - * Setup platform specific parts of CLCD driver 110 - */ 111 - int (*setup)(struct clcd_fb *); 112 - 113 - /* 114 - * mmap the framebuffer memory 115 - */ 116 - int (*mmap)(struct clcd_fb *, struct vm_area_struct *); 117 - 118 - /* 119 - * Remove platform specific parts of CLCD driver 120 - */ 121 - void (*remove)(struct clcd_fb *); 122 - }; 123 - 124 - struct amba_device; 125 - struct clk; 126 - 127 - /* this data structure describes each frame buffer device we find */ 128 - struct clcd_fb { 129 - struct fb_info fb; 130 - struct amba_device *dev; 131 - struct clk *clk; 132 - struct clcd_panel *panel; 133 - struct clcd_board *board; 134 - void *board_data; 135 - void __iomem *regs; 136 - u16 off_ienb; 137 - u16 off_cntl; 138 - u32 clcd_cntl; 139 - u32 cmap[16]; 140 - bool clk_enabled; 141 - }; 142 - 143 - static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) 144 - { 145 - struct fb_var_screeninfo *var = &fb->fb.var; 146 - u32 val, cpl; 147 - 148 - /* 149 - * Program the CLCD controller registers and start the CLCD 150 - */ 151 - val = ((var->xres / 16) - 1) << 2; 152 - val |= (var->hsync_len - 1) << 8; 153 - val |= (var->right_margin - 1) << 16; 154 - val |= (var->left_margin - 1) << 24; 155 - regs->tim0 = val; 156 - 157 - val = var->yres; 158 - if (fb->panel->cntl & CNTL_LCDDUAL) 159 - val /= 2; 160 - val -= 1; 161 - val |= (var->vsync_len - 1) << 10; 162 - val |= var->lower_margin << 16; 163 - val |= var->upper_margin << 24; 164 - regs->tim1 = val; 165 - 166 - val = fb->panel->tim2; 167 - val |= var->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : TIM2_IHS; 168 - val |= var->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS; 169 - 170 - cpl = var->xres_virtual; 171 - if (fb->panel->cntl & CNTL_LCDTFT) /* TFT */ 172 - /* / 1 */; 173 - else if (!var->grayscale) /* STN color */ 174 - cpl = cpl * 8 / 3; 175 - else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */ 176 - cpl /= 8; 177 - else /* STN monochrome, 4bit */ 178 - cpl /= 4; 179 - 180 - regs->tim2 = val | ((cpl - 1) << 16); 181 - 182 - regs->tim3 = fb->panel->tim3; 183 - 184 - val = fb->panel->cntl; 185 - if (var->grayscale) 186 - val |= CNTL_LCDBW; 187 - 188 - if (fb->panel->caps && fb->board->caps && var->bits_per_pixel >= 16) { 189 - /* 190 - * if board and panel supply capabilities, we can support 191 - * changing BGR/RGB depending on supplied parameters. Here 192 - * we switch to what the framebuffer is providing if need 193 - * be, so if the framebuffer is BGR but the display connection 194 - * is RGB (first case) we switch it around. Vice versa mutatis 195 - * mutandis if the framebuffer is RGB but the display connection 196 - * is BGR, we flip it around. 197 - */ 198 - if (var->red.offset == 0) 199 - val &= ~CNTL_BGR; 200 - else 201 - val |= CNTL_BGR; 202 - if (fb->panel->bgr_connection) 203 - val ^= CNTL_BGR; 204 - } 205 - 206 - switch (var->bits_per_pixel) { 207 - case 1: 208 - val |= CNTL_LCDBPP1; 209 - break; 210 - case 2: 211 - val |= CNTL_LCDBPP2; 212 - break; 213 - case 4: 214 - val |= CNTL_LCDBPP4; 215 - break; 216 - case 8: 217 - val |= CNTL_LCDBPP8; 218 - break; 219 - case 16: 220 - /* 221 - * PL110 cannot choose between 5551 and 565 modes in its 222 - * control register. It is possible to use 565 with 223 - * custom external wiring. 224 - */ 225 - if (amba_part(fb->dev) == 0x110 || 226 - var->green.length == 5) 227 - val |= CNTL_LCDBPP16; 228 - else if (var->green.length == 6) 229 - val |= CNTL_LCDBPP16_565; 230 - else 231 - val |= CNTL_LCDBPP16_444; 232 - break; 233 - case 32: 234 - val |= CNTL_LCDBPP24; 235 - break; 236 - } 237 - 238 - regs->cntl = val; 239 - regs->pixclock = var->pixclock; 240 - } 241 - 242 - static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var) 243 - { 244 - var->xres_virtual = var->xres = (var->xres + 15) & ~15; 245 - var->yres_virtual = var->yres = (var->yres + 1) & ~1; 246 - 247 - #define CHECK(e,l,h) (var->e < l || var->e > h) 248 - if (CHECK(right_margin, (5+1), 256) || /* back porch */ 249 - CHECK(left_margin, (5+1), 256) || /* front porch */ 250 - CHECK(hsync_len, (5+1), 256) || 251 - var->xres > 4096 || 252 - var->lower_margin > 255 || /* back porch */ 253 - var->upper_margin > 255 || /* front porch */ 254 - var->vsync_len > 32 || 255 - var->yres > 1024) 256 - return -EINVAL; 257 - #undef CHECK 258 - 259 - /* single panel mode: PCD = max(PCD, 1) */ 260 - /* dual panel mode: PCD = max(PCD, 5) */ 261 - 262 - /* 263 - * You can't change the grayscale setting, and 264 - * we can only do non-interlaced video. 265 - */ 266 - if (var->grayscale != fb->fb.var.grayscale || 267 - (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) 268 - return -EINVAL; 269 - 270 - #define CHECK(e) (var->e != fb->fb.var.e) 271 - if (fb->panel->fixedtimings && 272 - (CHECK(xres) || 273 - CHECK(yres) || 274 - CHECK(bits_per_pixel) || 275 - CHECK(pixclock) || 276 - CHECK(left_margin) || 277 - CHECK(right_margin) || 278 - CHECK(upper_margin) || 279 - CHECK(lower_margin) || 280 - CHECK(hsync_len) || 281 - CHECK(vsync_len) || 282 - CHECK(sync))) 283 - return -EINVAL; 284 - #undef CHECK 285 - 286 - var->nonstd = 0; 287 - var->accel_flags = 0; 288 - 289 - return 0; 290 - }
+3 -3
include/video/sticore.h
··· 2 2 #ifndef STICORE_H 3 3 #define STICORE_H 4 4 5 - struct fb_info; 5 + struct device; 6 6 7 7 /* generic STI structures & functions */ 8 8 ··· 367 367 /* PCI data structures (pg. 17ff from sti.pdf) */ 368 368 u8 rm_entry[16]; /* pci region mapper array == pci config space offset */ 369 369 370 - /* pointer to the fb_info where this STI device is used */ 371 - struct fb_info *info; 370 + /* pointer to the parent device */ 371 + struct device *dev; 372 372 373 373 /* pointer to all internal data */ 374 374 struct sti_all_data *sti_data;