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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13 328 lines 8.4 kB view raw
1/* 2 * drivers/video/tx3912fb.c 3 * 4 * Copyright (C) 1999 Harald Koerfgen 5 * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com) 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 * 11 * Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors 12 */ 13#include <linux/module.h> 14#include <linux/kernel.h> 15#include <linux/errno.h> 16#include <linux/string.h> 17#include <linux/tty.h> 18#include <linux/delay.h> 19#include <linux/interrupt.h> 20#include <linux/init.h> 21#include <linux/pm.h> 22#include <linux/fb.h> 23#include <asm/io.h> 24#include <asm/bootinfo.h> 25#include <asm/uaccess.h> 26#include <asm/tx3912.h> 27#include <video/tx3912.h> 28 29/* 30 * Frame buffer, palette and console structures 31 */ 32static struct fb_info fb_info; 33static u32 cfb8[16]; 34 35static struct fb_fix_screeninfo tx3912fb_fix __initdata = { 36 .id = "tx3912fb", 37 .smem_len = ((240 * 320)/2), 38 .type = FB_TYPE_PACKED_PIXELS, 39 .visual = FB_VISUAL_TRUECOLOR, 40 .xpanstep = 1, 41 .ypanstep = 1, 42 .ywrapstep = 1, 43 .accel = FB_ACCEL_NONE, 44}; 45 46static struct fb_var_screeninfo tx3912fb_var = { 47 .xres = 240, 48 .yres = 320, 49 .xres_virtual = 240, 50 .yres_virtual = 320, 51 .bits_per_pixel =4, 52 .red = { 0, 4, 0 }, /* ??? */ 53 .green = { 0, 4, 0 }, 54 .blue = { 0, 4, 0 }, 55 .activate = FB_ACTIVATE_NOW, 56 .width = -1, 57 .height = -1, 58 .pixclock = 20000, 59 .left_margin = 64, 60 .right_margin = 64, 61 .upper_margin = 32, 62 .lower_margin = 32, 63 .hsync_len = 64, 64 .vsync_len = 2, 65 .vmode = FB_VMODE_NONINTERLACED, 66}; 67 68/* 69 * Interface used by the world 70 */ 71int tx3912fb_init(void); 72 73static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green, 74 u_int blue, u_int transp, 75 struct fb_info *info); 76 77/* 78 * Macros 79 */ 80#define get_line_length(xres_virtual, bpp) \ 81 (u_long) (((int) xres_virtual * (int) bpp + 7) >> 3) 82 83/* 84 * Frame buffer operations structure used by console driver 85 */ 86static struct fb_ops tx3912fb_ops = { 87 .owner = THIS_MODULE, 88 .fb_setcolreg = tx3912fb_setcolreg, 89 .fb_fillrect = cfb_fillrect, 90 .fb_copyarea = cfb_copyarea, 91 .fb_imageblit = cfb_imageblit, 92 .fb_cursor = soft_cursor, 93}; 94 95static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 96{ 97 /* 98 * Memory limit 99 */ 100 line_length = 101 get_line_length(var->xres_virtual, var->bits_per_pixel); 102 if ((line_length * var->yres_virtual) > info->fix.smem_len) 103 return -ENOMEM; 104 105 return 0; 106} 107 108static int tx3912fb_set_par(struct fb_info *info) 109{ 110 u_long tx3912fb_paddr = 0; 111 112 /* Disable the video logic */ 113 outl(inl(TX3912_VIDEO_CTRL1) & 114 ~(TX3912_VIDEO_CTRL1_ENVID | TX3912_VIDEO_CTRL1_DISPON), 115 TX3912_VIDEO_CTRL1); 116 udelay(200); 117 118 /* Set start address for DMA transfer */ 119 outl(tx3912fb_paddr, TX3912_VIDEO_CTRL3); 120 121 /* Set end address for DMA transfer */ 122 outl((tx3912fb_paddr + tx3912fb_fix.smem_len + 1), TX3912_VIDEO_CTRL4); 123 124 /* Set the pixel depth */ 125 switch (info->var.bits_per_pixel) { 126 case 1: 127 /* Monochrome */ 128 outl(inl(TX3912_VIDEO_CTRL1) & 129 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 130 info->fix.visual = FB_VISUAL_MONO10; 131 break; 132 case 4: 133 /* 4-bit gray */ 134 outl(inl(TX3912_VIDEO_CTRL1) & 135 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 136 outl(inl(TX3912_VIDEO_CTRL1) | 137 TX3912_VIDEO_CTRL1_BITSEL_4BIT_GRAY, 138 TX3912_VIDEO_CTRL1); 139 info->fix.visual = FB_VISUAL_TRUECOLOR; 140 break; 141 case 8: 142 /* 8-bit color */ 143 outl(inl(TX3912_VIDEO_CTRL1) & 144 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 145 outl(inl(TX3912_VIDEO_CTRL1) | 146 TX3912_VIDEO_CTRL1_BITSEL_8BIT_COLOR, 147 TX3912_VIDEO_CTRL1); 148 info->fix.visual = FB_VISUAL_TRUECOLOR; 149 break; 150 case 2: 151 default: 152 /* 2-bit gray */ 153 outl(inl(TX3912_VIDEO_CTRL1) & 154 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 155 outl(inl(TX3912_VIDEO_CTRL1) | 156 TX3912_VIDEO_CTRL1_BITSEL_2BIT_GRAY, 157 TX3912_VIDEO_CTRL1); 158 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 159 break; 160 } 161 162 /* Enable the video clock */ 163 outl(inl(TX3912_CLK_CTRL) | TX3912_CLK_CTRL_ENVIDCLK, 164 TX3912_CLK_CTRL); 165 166 /* Unfreeze video logic and enable DF toggle */ 167 outl(inl(TX3912_VIDEO_CTRL1) & 168 ~(TX3912_VIDEO_CTRL1_ENFREEZEFRAME | 169 TX3912_VIDEO_CTRL1_DFMODE) 170 , TX3912_VIDEO_CTRL1); 171 udelay(200); 172 173 /* Enable the video logic */ 174 outl(inl(TX3912_VIDEO_CTRL1) | 175 (TX3912_VIDEO_CTRL1_ENVID | TX3912_VIDEO_CTRL1_DISPON), 176 TX3912_VIDEO_CTRL1); 177 178 info->fix.line_length = get_line_length(var->xres_virtual, 179 var->bits_per_pixel); 180} 181 182/* 183 * Set a single color register 184 */ 185static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green, 186 u_int blue, u_int transp, 187 struct fb_info *info) 188{ 189 if (regno > 255) 190 return 1; 191 192 if (regno < 16) 193 ((u32 *)(info->pseudo_palette))[regno] = ((red & 0xe000) >> 8) 194 | ((green & 0xe000) >> 11) 195 | ((blue & 0xc000) >> 14); 196 return 0; 197} 198 199int __init tx3912fb_setup(char *options); 200 201/* 202 * Initialization of the framebuffer 203 */ 204int __init tx3912fb_init(void) 205{ 206 u_long tx3912fb_paddr = 0; 207 int size = (info->var.bits_per_pixel == 8) ? 256 : 16; 208 char *option = NULL; 209 210 if (fb_get_options("tx3912fb", &option)) 211 return -ENODEV; 212 tx3912fb_setup(option); 213 214 /* Disable the video logic */ 215 outl(inl(TX3912_VIDEO_CTRL1) & 216 ~(TX3912_VIDEO_CTRL1_ENVID | TX3912_VIDEO_CTRL1_DISPON), 217 TX3912_VIDEO_CTRL1); 218 udelay(200); 219 220 /* Set start address for DMA transfer */ 221 outl(tx3912fb_paddr, TX3912_VIDEO_CTRL3); 222 223 /* Set end address for DMA transfer */ 224 outl((tx3912fb_paddr + tx3912fb_fix.smem_len + 1), TX3912_VIDEO_CTRL4); 225 226 /* Set the pixel depth */ 227 switch (tx3912fb_var.bits_per_pixel) { 228 case 1: 229 /* Monochrome */ 230 outl(inl(TX3912_VIDEO_CTRL1) & 231 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 232 tx3912fb_fix.visual = FB_VISUAL_MONO10; 233 break; 234 case 4: 235 /* 4-bit gray */ 236 outl(inl(TX3912_VIDEO_CTRL1) & 237 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 238 outl(inl(TX3912_VIDEO_CTRL1) | 239 TX3912_VIDEO_CTRL1_BITSEL_4BIT_GRAY, 240 TX3912_VIDEO_CTRL1); 241 tx3912fb_fix.visual = FB_VISUAL_TRUECOLOR; 242 tx3912fb_fix.grayscale = 1; 243 break; 244 case 8: 245 /* 8-bit color */ 246 outl(inl(TX3912_VIDEO_CTRL1) & 247 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 248 outl(inl(TX3912_VIDEO_CTRL1) | 249 TX3912_VIDEO_CTRL1_BITSEL_8BIT_COLOR, 250 TX3912_VIDEO_CTRL1); 251 tx3912fb_fix.visual = FB_VISUAL_TRUECOLOR; 252 break; 253 case 2: 254 default: 255 /* 2-bit gray */ 256 outl(inl(TX3912_VIDEO_CTRL1) & 257 ~TX3912_VIDEO_CTRL1_BITSEL_MASK, TX3912_VIDEO_CTRL1); 258 outl(inl(TX3912_VIDEO_CTRL1) | 259 TX3912_VIDEO_CTRL1_BITSEL_2BIT_GRAY, 260 TX3912_VIDEO_CTRL1); 261 tx3912fb_fix.visual = FB_VISUAL_PSEUDOCOLOR; 262 tx3912fb_fix.grayscale = 1; 263 break; 264 } 265 266 /* Enable the video clock */ 267 outl(inl(TX3912_CLK_CTRL) | TX3912_CLK_CTRL_ENVIDCLK, 268 TX3912_CLK_CTRL); 269 270 /* Unfreeze video logic and enable DF toggle */ 271 outl(inl(TX3912_VIDEO_CTRL1) & 272 ~(TX3912_VIDEO_CTRL1_ENFREEZEFRAME | TX3912_VIDEO_CTRL1_DFMODE), 273 TX3912_VIDEO_CTRL1); 274 udelay(200); 275 276 /* Clear the framebuffer */ 277 memset((void *) tx3912fb_fix.smem_start, 0xff, tx3912fb_fix.smem_len); 278 udelay(200); 279 280 /* Enable the video logic */ 281 outl(inl(TX3912_VIDEO_CTRL1) | 282 (TX3912_VIDEO_CTRL1_ENVID | TX3912_VIDEO_CTRL1_DISPON), 283 TX3912_VIDEO_CTRL1); 284 285 /* 286 * Memory limit 287 */ 288 tx3912fb_fix.line_length = 289 get_line_length(tx3912fb_var.xres_virtual, tx3912fb_var.bits_per_pixel); 290 if ((tx3912fb_fix.line_length * tx3912fb_var.yres_virtual) > tx3912fb_fix.smem_len) 291 return -ENOMEM; 292 293 fb_info.fbops = &tx3912fb_ops; 294 fb_info.var = tx3912fb_var; 295 fb_info.fix = tx3912fb_fix; 296 fb_info.pseudo_palette = pseudo_palette; 297 fb_info.flags = FBINFO_DEFAULT; 298 299 /* Clear the framebuffer */ 300 memset((void *) fb_info.fix.smem_start, 0xff, fb_info.fix.smem_len); 301 udelay(200); 302 303 fb_alloc_cmap(&info->cmap, size, 0); 304 305 if (register_framebuffer(&fb_info) < 0) 306 return -1; 307 308 printk(KERN_INFO "fb%d: TX3912 frame buffer using %uKB.\n", 309 fb_info.node, (u_int) (fb_info.fix.smem_len >> 10)); 310 return 0; 311} 312 313int __init tx3912fb_setup(char *options) 314{ 315 char *this_opt; 316 317 if (!options || !*options) 318 return 0; 319 320 while ((this_opt = strsep(&options, ","))) { 321 if (!strncmp(options, "bpp:", 4)) 322 tx3912fb_var.bits_per_pixel = simple_strtoul(options+4, NULL, 0); 323 } 324 return 0; 325} 326 327module_init(tx3912fb_init); 328MODULE_LICENSE("GPL");