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