tmiofb.c (27937B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller 4 * 5 * Copyright(C) 2005-2006 Chris Humbert 6 * Copyright(C) 2005 Dirk Opfer 7 * Copytight(C) 2007,2008 Dmitry Baryshkov 8 * 9 * Based on: 10 * drivers/video/w100fb.c 11 * code written by Sharp/Lineo for 2.4 kernels 12 */ 13 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/platform_device.h> 17#include <linux/fb.h> 18#include <linux/interrupt.h> 19#include <linux/delay.h> 20/* Why should fb driver call console functions? because console_lock() */ 21#include <linux/console.h> 22#include <linux/mfd/core.h> 23#include <linux/mfd/tmio.h> 24#include <linux/uaccess.h> 25 26/* 27 * accelerator commands 28 */ 29#define TMIOFB_ACC_CSADR(x) (0x00000000 | ((x) & 0x001ffffe)) 30#define TMIOFB_ACC_CHPIX(x) (0x01000000 | ((x) & 0x000003ff)) 31#define TMIOFB_ACC_CVPIX(x) (0x02000000 | ((x) & 0x000003ff)) 32#define TMIOFB_ACC_PSADR(x) (0x03000000 | ((x) & 0x00fffffe)) 33#define TMIOFB_ACC_PHPIX(x) (0x04000000 | ((x) & 0x000003ff)) 34#define TMIOFB_ACC_PVPIX(x) (0x05000000 | ((x) & 0x000003ff)) 35#define TMIOFB_ACC_PHOFS(x) (0x06000000 | ((x) & 0x000003ff)) 36#define TMIOFB_ACC_PVOFS(x) (0x07000000 | ((x) & 0x000003ff)) 37#define TMIOFB_ACC_POADR(x) (0x08000000 | ((x) & 0x00fffffe)) 38#define TMIOFB_ACC_RSTR(x) (0x09000000 | ((x) & 0x000000ff)) 39#define TMIOFB_ACC_TCLOR(x) (0x0A000000 | ((x) & 0x0000ffff)) 40#define TMIOFB_ACC_FILL(x) (0x0B000000 | ((x) & 0x0000ffff)) 41#define TMIOFB_ACC_DSADR(x) (0x0C000000 | ((x) & 0x00fffffe)) 42#define TMIOFB_ACC_SSADR(x) (0x0D000000 | ((x) & 0x00fffffe)) 43#define TMIOFB_ACC_DHPIX(x) (0x0E000000 | ((x) & 0x000003ff)) 44#define TMIOFB_ACC_DVPIX(x) (0x0F000000 | ((x) & 0x000003ff)) 45#define TMIOFB_ACC_SHPIX(x) (0x10000000 | ((x) & 0x000003ff)) 46#define TMIOFB_ACC_SVPIX(x) (0x11000000 | ((x) & 0x000003ff)) 47#define TMIOFB_ACC_LBINI(x) (0x12000000 | ((x) & 0x0000ffff)) 48#define TMIOFB_ACC_LBK2(x) (0x13000000 | ((x) & 0x0000ffff)) 49#define TMIOFB_ACC_SHBINI(x) (0x14000000 | ((x) & 0x0000ffff)) 50#define TMIOFB_ACC_SHBK2(x) (0x15000000 | ((x) & 0x0000ffff)) 51#define TMIOFB_ACC_SVBINI(x) (0x16000000 | ((x) & 0x0000ffff)) 52#define TMIOFB_ACC_SVBK2(x) (0x17000000 | ((x) & 0x0000ffff)) 53 54#define TMIOFB_ACC_CMGO 0x20000000 55#define TMIOFB_ACC_CMGO_CEND 0x00000001 56#define TMIOFB_ACC_CMGO_INT 0x00000002 57#define TMIOFB_ACC_CMGO_CMOD 0x00000010 58#define TMIOFB_ACC_CMGO_CDVRV 0x00000020 59#define TMIOFB_ACC_CMGO_CDHRV 0x00000040 60#define TMIOFB_ACC_CMGO_RUND 0x00008000 61#define TMIOFB_ACC_SCGO 0x21000000 62#define TMIOFB_ACC_SCGO_CEND 0x00000001 63#define TMIOFB_ACC_SCGO_INT 0x00000002 64#define TMIOFB_ACC_SCGO_ROP3 0x00000004 65#define TMIOFB_ACC_SCGO_TRNS 0x00000008 66#define TMIOFB_ACC_SCGO_DVRV 0x00000010 67#define TMIOFB_ACC_SCGO_DHRV 0x00000020 68#define TMIOFB_ACC_SCGO_SVRV 0x00000040 69#define TMIOFB_ACC_SCGO_SHRV 0x00000080 70#define TMIOFB_ACC_SCGO_DSTXY 0x00008000 71#define TMIOFB_ACC_SBGO 0x22000000 72#define TMIOFB_ACC_SBGO_CEND 0x00000001 73#define TMIOFB_ACC_SBGO_INT 0x00000002 74#define TMIOFB_ACC_SBGO_DVRV 0x00000010 75#define TMIOFB_ACC_SBGO_DHRV 0x00000020 76#define TMIOFB_ACC_SBGO_SVRV 0x00000040 77#define TMIOFB_ACC_SBGO_SHRV 0x00000080 78#define TMIOFB_ACC_SBGO_SBMD 0x00000100 79#define TMIOFB_ACC_FLGO 0x23000000 80#define TMIOFB_ACC_FLGO_CEND 0x00000001 81#define TMIOFB_ACC_FLGO_INT 0x00000002 82#define TMIOFB_ACC_FLGO_ROP3 0x00000004 83#define TMIOFB_ACC_LDGO 0x24000000 84#define TMIOFB_ACC_LDGO_CEND 0x00000001 85#define TMIOFB_ACC_LDGO_INT 0x00000002 86#define TMIOFB_ACC_LDGO_ROP3 0x00000004 87#define TMIOFB_ACC_LDGO_ENDPX 0x00000008 88#define TMIOFB_ACC_LDGO_LVRV 0x00000010 89#define TMIOFB_ACC_LDGO_LHRV 0x00000020 90#define TMIOFB_ACC_LDGO_LDMOD 0x00000040 91 92/* a FIFO is always allocated, even if acceleration is not used */ 93#define TMIOFB_FIFO_SIZE 512 94 95/* 96 * LCD Host Controller Configuration Register 97 * 98 * This iomem area supports only 16-bit IO. 99 */ 100#define CCR_CMD 0x04 /* Command */ 101#define CCR_REVID 0x08 /* Revision ID */ 102#define CCR_BASEL 0x10 /* LCD Control Reg Base Addr Low */ 103#define CCR_BASEH 0x12 /* LCD Control Reg Base Addr High */ 104#define CCR_UGCC 0x40 /* Unified Gated Clock Control */ 105#define CCR_GCC 0x42 /* Gated Clock Control */ 106#define CCR_USC 0x50 /* Unified Software Clear */ 107#define CCR_VRAMRTC 0x60 /* VRAM Timing Control */ 108 /* 0x61 VRAM Refresh Control */ 109#define CCR_VRAMSAC 0x62 /* VRAM Access Control */ 110 /* 0x63 VRAM Status */ 111#define CCR_VRAMBC 0x64 /* VRAM Block Control */ 112 113/* 114 * LCD Control Register 115 * 116 * This iomem area supports only 16-bit IO. 117 */ 118#define LCR_UIS 0x000 /* Unified Interrupt Status */ 119#define LCR_VHPN 0x008 /* VRAM Horizontal Pixel Number */ 120#define LCR_CFSAL 0x00a /* Command FIFO Start Address Low */ 121#define LCR_CFSAH 0x00c /* Command FIFO Start Address High */ 122#define LCR_CFS 0x00e /* Command FIFO Size */ 123#define LCR_CFWS 0x010 /* Command FIFO Writeable Size */ 124#define LCR_BBIE 0x012 /* BitBLT Interrupt Enable */ 125#define LCR_BBISC 0x014 /* BitBLT Interrupt Status and Clear */ 126#define LCR_CCS 0x016 /* Command Count Status */ 127#define LCR_BBES 0x018 /* BitBLT Execution Status */ 128#define LCR_CMDL 0x01c /* Command Low */ 129#define LCR_CMDH 0x01e /* Command High */ 130#define LCR_CFC 0x022 /* Command FIFO Clear */ 131#define LCR_CCIFC 0x024 /* CMOS Camera IF Control */ 132#define LCR_HWT 0x026 /* Hardware Test */ 133#define LCR_LCDCCRC 0x100 /* LCDC Clock and Reset Control */ 134#define LCR_LCDCC 0x102 /* LCDC Control */ 135#define LCR_LCDCOPC 0x104 /* LCDC Output Pin Control */ 136#define LCR_LCDIS 0x108 /* LCD Interrupt Status */ 137#define LCR_LCDIM 0x10a /* LCD Interrupt Mask */ 138#define LCR_LCDIE 0x10c /* LCD Interrupt Enable */ 139#define LCR_GDSAL 0x122 /* Graphics Display Start Address Low */ 140#define LCR_GDSAH 0x124 /* Graphics Display Start Address High */ 141#define LCR_VHPCL 0x12a /* VRAM Horizontal Pixel Count Low */ 142#define LCR_VHPCH 0x12c /* VRAM Horizontal Pixel Count High */ 143#define LCR_GM 0x12e /* Graphic Mode(VRAM access enable) */ 144#define LCR_HT 0x140 /* Horizontal Total */ 145#define LCR_HDS 0x142 /* Horizontal Display Start */ 146#define LCR_HSS 0x144 /* H-Sync Start */ 147#define LCR_HSE 0x146 /* H-Sync End */ 148#define LCR_HNP 0x14c /* Horizontal Number of Pixels */ 149#define LCR_VT 0x150 /* Vertical Total */ 150#define LCR_VDS 0x152 /* Vertical Display Start */ 151#define LCR_VSS 0x154 /* V-Sync Start */ 152#define LCR_VSE 0x156 /* V-Sync End */ 153#define LCR_CDLN 0x160 /* Current Display Line Number */ 154#define LCR_ILN 0x162 /* Interrupt Line Number */ 155#define LCR_SP 0x164 /* Sync Polarity */ 156#define LCR_MISC 0x166 /* MISC(RGB565 mode) */ 157#define LCR_VIHSS 0x16a /* Video Interface H-Sync Start */ 158#define LCR_VIVS 0x16c /* Video Interface Vertical Start */ 159#define LCR_VIVE 0x16e /* Video Interface Vertical End */ 160#define LCR_VIVSS 0x170 /* Video Interface V-Sync Start */ 161#define LCR_VCCIS 0x17e /* Video / CMOS Camera Interface Select */ 162#define LCR_VIDWSAL 0x180 /* VI Data Write Start Address Low */ 163#define LCR_VIDWSAH 0x182 /* VI Data Write Start Address High */ 164#define LCR_VIDRSAL 0x184 /* VI Data Read Start Address Low */ 165#define LCR_VIDRSAH 0x186 /* VI Data Read Start Address High */ 166#define LCR_VIPDDST 0x188 /* VI Picture Data Display Start Timing */ 167#define LCR_VIPDDET 0x186 /* VI Picture Data Display End Timing */ 168#define LCR_VIE 0x18c /* Video Interface Enable */ 169#define LCR_VCS 0x18e /* Video/Camera Select */ 170#define LCR_VPHWC 0x194 /* Video Picture Horizontal Wait Count */ 171#define LCR_VPHS 0x196 /* Video Picture Horizontal Size */ 172#define LCR_VPVWC 0x198 /* Video Picture Vertical Wait Count */ 173#define LCR_VPVS 0x19a /* Video Picture Vertical Size */ 174#define LCR_PLHPIX 0x1a0 /* PLHPIX */ 175#define LCR_XS 0x1a2 /* XStart */ 176#define LCR_XCKHW 0x1a4 /* XCK High Width */ 177#define LCR_STHS 0x1a8 /* STH Start */ 178#define LCR_VT2 0x1aa /* Vertical Total */ 179#define LCR_YCKSW 0x1ac /* YCK Start Wait */ 180#define LCR_YSTS 0x1ae /* YST Start */ 181#define LCR_PPOLS 0x1b0 /* #PPOL Start */ 182#define LCR_PRECW 0x1b2 /* PREC Width */ 183#define LCR_VCLKHW 0x1b4 /* VCLK High Width */ 184#define LCR_OC 0x1b6 /* Output Control */ 185 186static char *mode_option; 187 188struct tmiofb_par { 189 u32 pseudo_palette[16]; 190 191#ifdef CONFIG_FB_TMIO_ACCELL 192 wait_queue_head_t wait_acc; 193 bool use_polling; 194#endif 195 196 void __iomem *ccr; 197 void __iomem *lcr; 198}; 199 200/*--------------------------------------------------------------------------*/ 201 202/* 203 * reasons for an interrupt: 204 * uis bbisc lcdis 205 * 0100 0001 accelerator command completed 206 * 2000 0001 vsync start 207 * 2000 0002 display start 208 * 2000 0004 line number match(0x1ff mask???) 209 */ 210static irqreturn_t tmiofb_irq(int irq, void *__info) 211{ 212 struct fb_info *info = __info; 213 struct tmiofb_par *par = info->par; 214 unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC); 215 216 217 tmio_iowrite16(bbisc, par->lcr + LCR_BBISC); 218 219#ifdef CONFIG_FB_TMIO_ACCELL 220 /* 221 * We were in polling mode and now we got correct irq. 222 * Switch back to IRQ-based sync of command FIFO 223 */ 224 if (unlikely(par->use_polling && irq != -1)) { 225 printk(KERN_INFO "tmiofb: switching to waitq\n"); 226 par->use_polling = false; 227 } 228 229 if (bbisc & 1) 230 wake_up(&par->wait_acc); 231#endif 232 233 return IRQ_HANDLED; 234} 235 236 237/*--------------------------------------------------------------------------*/ 238 239 240/* 241 * Turns off the LCD controller and LCD host controller. 242 */ 243static int tmiofb_hw_stop(struct platform_device *dev) 244{ 245 struct tmio_fb_data *data = dev_get_platdata(&dev->dev); 246 struct fb_info *info = platform_get_drvdata(dev); 247 struct tmiofb_par *par = info->par; 248 249 tmio_iowrite16(0, par->ccr + CCR_UGCC); 250 tmio_iowrite16(0, par->lcr + LCR_GM); 251 data->lcd_set_power(dev, 0); 252 tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); 253 254 return 0; 255} 256 257/* 258 * Initializes the LCD host controller. 259 */ 260static int tmiofb_hw_init(struct platform_device *dev) 261{ 262 const struct mfd_cell *cell = mfd_get_cell(dev); 263 struct fb_info *info = platform_get_drvdata(dev); 264 struct tmiofb_par *par = info->par; 265 const struct resource *nlcr = &cell->resources[0]; 266 const struct resource *vram = &cell->resources[2]; 267 unsigned long base; 268 269 if (nlcr == NULL || vram == NULL) 270 return -EINVAL; 271 272 base = nlcr->start; 273 274 tmio_iowrite16(0x003a, par->ccr + CCR_UGCC); 275 tmio_iowrite16(0x003a, par->ccr + CCR_GCC); 276 tmio_iowrite16(0x3f00, par->ccr + CCR_USC); 277 278 msleep(2); /* wait for device to settle */ 279 280 tmio_iowrite16(0x0000, par->ccr + CCR_USC); 281 tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH); 282 tmio_iowrite16(base, par->ccr + CCR_BASEL); 283 tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */ 284 tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */ 285 tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */ 286 tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC); 287 msleep(2); /* wait for device to settle */ 288 tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC); 289 290 base = vram->start + info->screen_size; 291 tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH); 292 tmio_iowrite16(base, par->lcr + LCR_CFSAL); 293 tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS); 294 tmio_iowrite16(1, par->lcr + LCR_CFC); 295 tmio_iowrite16(1, par->lcr + LCR_BBIE); 296 tmio_iowrite16(0, par->lcr + LCR_CFWS); 297 298 return 0; 299} 300 301/* 302 * Sets the LCD controller's output resolution and pixel clock 303 */ 304static void tmiofb_hw_mode(struct platform_device *dev) 305{ 306 struct tmio_fb_data *data = dev_get_platdata(&dev->dev); 307 struct fb_info *info = platform_get_drvdata(dev); 308 struct fb_videomode *mode = info->mode; 309 struct tmiofb_par *par = info->par; 310 unsigned int i; 311 312 tmio_iowrite16(0, par->lcr + LCR_GM); 313 data->lcd_set_power(dev, 0); 314 tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); 315 data->lcd_mode(dev, mode); 316 data->lcd_set_power(dev, 1); 317 318 tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN); 319 tmio_iowrite16(0, par->lcr + LCR_GDSAH); 320 tmio_iowrite16(0, par->lcr + LCR_GDSAL); 321 tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH); 322 tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL); 323 tmio_iowrite16(i = 0, par->lcr + LCR_HSS); 324 tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE); 325 tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS); 326 tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT); 327 tmio_iowrite16(mode->xres, par->lcr + LCR_HNP); 328 tmio_iowrite16(i = 0, par->lcr + LCR_VSS); 329 tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE); 330 tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS); 331 tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN); 332 tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT); 333 tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */ 334 tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */ 335 tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC); 336 tmio_iowrite16(3, par->lcr + LCR_SP); /* sync polarity */ 337 338 tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC); 339 msleep(5); /* wait for device to settle */ 340 tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */ 341 msleep(5); /* wait for device to settle */ 342 tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/ 343 tmio_iowrite16(0xfffa, par->lcr + LCR_VCS); 344} 345 346/*--------------------------------------------------------------------------*/ 347 348#ifdef CONFIG_FB_TMIO_ACCELL 349static int __must_check 350tmiofb_acc_wait(struct fb_info *info, unsigned int ccs) 351{ 352 struct tmiofb_par *par = info->par; 353 /* 354 * This code can be called with interrupts disabled. 355 * So instead of relaying on irq to trigger the event, 356 * poll the state till the necessary command is executed. 357 */ 358 if (irqs_disabled() || par->use_polling) { 359 int i = 0; 360 while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) { 361 udelay(1); 362 i++; 363 if (i > 10000) { 364 pr_err("tmiofb: timeout waiting for %d\n", 365 ccs); 366 return -ETIMEDOUT; 367 } 368 tmiofb_irq(-1, info); 369 } 370 } else { 371 if (!wait_event_interruptible_timeout(par->wait_acc, 372 tmio_ioread16(par->lcr + LCR_CCS) <= ccs, 373 1000)) { 374 pr_err("tmiofb: timeout waiting for %d\n", ccs); 375 return -ETIMEDOUT; 376 } 377 } 378 379 return 0; 380} 381 382/* 383 * Writes an accelerator command to the accelerator's FIFO. 384 */ 385static int 386tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count) 387{ 388 struct tmiofb_par *par = info->par; 389 int ret; 390 391 ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count); 392 if (ret) 393 return ret; 394 395 for (; count; count--, cmd++) { 396 tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH); 397 tmio_iowrite16(*cmd, par->lcr + LCR_CMDL); 398 } 399 400 return ret; 401} 402 403/* 404 * Wait for the accelerator to finish its operations before writing 405 * to the framebuffer for consistent display output. 406 */ 407static int tmiofb_sync(struct fb_info *fbi) 408{ 409 struct tmiofb_par *par = fbi->par; 410 411 int ret; 412 int i = 0; 413 414 ret = tmiofb_acc_wait(fbi, 0); 415 416 while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */ 417 udelay(1); 418 i++ ; 419 if (i > 10000) { 420 printk(KERN_ERR "timeout waiting for blit to end!\n"); 421 return -ETIMEDOUT; 422 } 423 } 424 425 return ret; 426} 427 428static void 429tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect) 430{ 431 const u32 cmd[] = { 432 TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2), 433 TMIOFB_ACC_DHPIX(rect->width - 1), 434 TMIOFB_ACC_DVPIX(rect->height - 1), 435 TMIOFB_ACC_FILL(rect->color), 436 TMIOFB_ACC_FLGO, 437 }; 438 439 if (fbi->state != FBINFO_STATE_RUNNING || 440 fbi->flags & FBINFO_HWACCEL_DISABLED) { 441 cfb_fillrect(fbi, rect); 442 return; 443 } 444 445 tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); 446} 447 448static void 449tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area) 450{ 451 const u32 cmd[] = { 452 TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2), 453 TMIOFB_ACC_DHPIX(area->width - 1), 454 TMIOFB_ACC_DVPIX(area->height - 1), 455 TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2), 456 TMIOFB_ACC_SCGO, 457 }; 458 459 if (fbi->state != FBINFO_STATE_RUNNING || 460 fbi->flags & FBINFO_HWACCEL_DISABLED) { 461 cfb_copyarea(fbi, area); 462 return; 463 } 464 465 tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd)); 466} 467#endif 468 469static void tmiofb_clearscreen(struct fb_info *info) 470{ 471 const struct fb_fillrect rect = { 472 .dx = 0, 473 .dy = 0, 474 .width = info->mode->xres, 475 .height = info->mode->yres, 476 .color = 0, 477 .rop = ROP_COPY, 478 }; 479 480 info->fbops->fb_fillrect(info, &rect); 481} 482 483static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank) 484{ 485 struct tmiofb_par *par = fbi->par; 486 struct fb_videomode *mode = fbi->mode; 487 unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN); 488 unsigned int vds = mode->vsync_len + mode->upper_margin; 489 490 vblank->vcount = vcount; 491 vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT 492 | FB_VBLANK_HAVE_VSYNC; 493 494 if (vcount < mode->vsync_len) 495 vblank->flags |= FB_VBLANK_VSYNCING; 496 497 if (vcount < vds || vcount > vds + mode->yres) 498 vblank->flags |= FB_VBLANK_VBLANKING; 499 500 return 0; 501} 502 503 504static int tmiofb_ioctl(struct fb_info *fbi, 505 unsigned int cmd, unsigned long arg) 506{ 507 switch (cmd) { 508 case FBIOGET_VBLANK: { 509 struct fb_vblank vblank = {0}; 510 void __user *argp = (void __user *) arg; 511 512 tmiofb_vblank(fbi, &vblank); 513 if (copy_to_user(argp, &vblank, sizeof vblank)) 514 return -EFAULT; 515 return 0; 516 } 517 518#ifdef CONFIG_FB_TMIO_ACCELL 519 case FBIO_TMIO_ACC_SYNC: 520 tmiofb_sync(fbi); 521 return 0; 522 523 case FBIO_TMIO_ACC_WRITE: { 524 u32 __user *argp = (void __user *) arg; 525 u32 len; 526 u32 acc[16]; 527 528 if (get_user(len, argp)) 529 return -EFAULT; 530 if (len > ARRAY_SIZE(acc)) 531 return -EINVAL; 532 if (copy_from_user(acc, argp + 1, sizeof(u32) * len)) 533 return -EFAULT; 534 535 return tmiofb_acc_write(fbi, acc, len); 536 } 537#endif 538 } 539 540 return -ENOTTY; 541} 542 543/*--------------------------------------------------------------------------*/ 544 545/* Select the smallest mode that allows the desired resolution to be 546 * displayed. If desired, the x and y parameters can be rounded up to 547 * match the selected mode. 548 */ 549static struct fb_videomode * 550tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) 551{ 552 struct tmio_fb_data *data = dev_get_platdata(info->device); 553 struct fb_videomode *best = NULL; 554 int i; 555 556 for (i = 0; i < data->num_modes; i++) { 557 struct fb_videomode *mode = data->modes + i; 558 559 if (mode->xres >= var->xres && mode->yres >= var->yres 560 && (!best || (mode->xres < best->xres 561 && mode->yres < best->yres))) 562 best = mode; 563 } 564 565 return best; 566} 567 568static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 569{ 570 571 struct fb_videomode *mode; 572 struct tmio_fb_data *data = dev_get_platdata(info->device); 573 574 mode = tmiofb_find_mode(info, var); 575 if (!mode || var->bits_per_pixel > 16) 576 return -EINVAL; 577 578 fb_videomode_to_var(var, mode); 579 580 var->xres_virtual = mode->xres; 581 var->yres_virtual = info->screen_size / (mode->xres * 2); 582 583 if (var->yres_virtual < var->yres) 584 return -EINVAL; 585 586 var->xoffset = 0; 587 var->yoffset = 0; 588 var->bits_per_pixel = 16; 589 var->grayscale = 0; 590 var->red.offset = 11; 591 var->red.length = 5; 592 var->green.offset = 5; 593 var->green.length = 6; 594 var->blue.offset = 0; 595 var->blue.length = 5; 596 var->transp.offset = 0; 597 var->transp.length = 0; 598 var->nonstd = 0; 599 var->height = data->height; /* mm */ 600 var->width = data->width; /* mm */ 601 var->rotate = 0; 602 return 0; 603} 604 605static int tmiofb_set_par(struct fb_info *info) 606{ 607 struct fb_var_screeninfo *var = &info->var; 608 struct fb_videomode *mode; 609 610 mode = tmiofb_find_mode(info, var); 611 if (!mode) 612 return -EINVAL; 613 614 info->mode = mode; 615 info->fix.line_length = info->mode->xres * 616 var->bits_per_pixel / 8; 617 618 tmiofb_hw_mode(to_platform_device(info->device)); 619 tmiofb_clearscreen(info); 620 return 0; 621} 622 623static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green, 624 unsigned blue, unsigned transp, 625 struct fb_info *info) 626{ 627 struct tmiofb_par *par = info->par; 628 629 if (regno < ARRAY_SIZE(par->pseudo_palette)) { 630 par->pseudo_palette[regno] = 631 ((red & 0xf800)) | 632 ((green & 0xfc00) >> 5) | 633 ((blue & 0xf800) >> 11); 634 return 0; 635 } 636 637 return -EINVAL; 638} 639 640static int tmiofb_blank(int blank, struct fb_info *info) 641{ 642 /* 643 * everything is done in lcd/bl drivers. 644 * this is purely to make sysfs happy and work. 645 */ 646 return 0; 647} 648 649static const struct fb_ops tmiofb_ops = { 650 .owner = THIS_MODULE, 651 652 .fb_ioctl = tmiofb_ioctl, 653 .fb_check_var = tmiofb_check_var, 654 .fb_set_par = tmiofb_set_par, 655 .fb_setcolreg = tmiofb_setcolreg, 656 .fb_blank = tmiofb_blank, 657 .fb_imageblit = cfb_imageblit, 658#ifdef CONFIG_FB_TMIO_ACCELL 659 .fb_sync = tmiofb_sync, 660 .fb_fillrect = tmiofb_fillrect, 661 .fb_copyarea = tmiofb_copyarea, 662#else 663 .fb_fillrect = cfb_fillrect, 664 .fb_copyarea = cfb_copyarea, 665#endif 666}; 667 668/*--------------------------------------------------------------------------*/ 669 670static int tmiofb_probe(struct platform_device *dev) 671{ 672 const struct mfd_cell *cell = mfd_get_cell(dev); 673 struct tmio_fb_data *data = dev_get_platdata(&dev->dev); 674 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); 675 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); 676 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); 677 int irq = platform_get_irq(dev, 0); 678 struct fb_info *info; 679 struct tmiofb_par *par; 680 int retval; 681 682 /* 683 * This is the only way ATM to disable the fb 684 */ 685 if (data == NULL) { 686 dev_err(&dev->dev, "NULL platform data!\n"); 687 return -EINVAL; 688 } 689 if (ccr == NULL || lcr == NULL || vram == NULL || irq < 0) { 690 dev_err(&dev->dev, "missing resources\n"); 691 return -EINVAL; 692 } 693 694 info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev); 695 696 if (!info) 697 return -ENOMEM; 698 699 par = info->par; 700 701#ifdef CONFIG_FB_TMIO_ACCELL 702 init_waitqueue_head(&par->wait_acc); 703 704 par->use_polling = true; 705 706 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA 707 | FBINFO_HWACCEL_FILLRECT; 708#else 709 info->flags = FBINFO_DEFAULT; 710#endif 711 712 info->fbops = &tmiofb_ops; 713 714 strcpy(info->fix.id, "tmio-fb"); 715 info->fix.smem_start = vram->start; 716 info->fix.smem_len = resource_size(vram); 717 info->fix.type = FB_TYPE_PACKED_PIXELS; 718 info->fix.visual = FB_VISUAL_TRUECOLOR; 719 info->fix.mmio_start = lcr->start; 720 info->fix.mmio_len = resource_size(lcr); 721 info->fix.accel = FB_ACCEL_NONE; 722 info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE); 723 info->pseudo_palette = par->pseudo_palette; 724 725 par->ccr = ioremap(ccr->start, resource_size(ccr)); 726 if (!par->ccr) { 727 retval = -ENOMEM; 728 goto err_ioremap_ccr; 729 } 730 731 par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len); 732 if (!par->lcr) { 733 retval = -ENOMEM; 734 goto err_ioremap_lcr; 735 } 736 737 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 738 if (!info->screen_base) { 739 retval = -ENOMEM; 740 goto err_ioremap_vram; 741 } 742 743 retval = request_irq(irq, &tmiofb_irq, 0, 744 dev_name(&dev->dev), info); 745 746 if (retval) 747 goto err_request_irq; 748 749 platform_set_drvdata(dev, info); 750 751 retval = fb_find_mode(&info->var, info, mode_option, 752 data->modes, data->num_modes, 753 data->modes, 16); 754 if (!retval) { 755 retval = -EINVAL; 756 goto err_find_mode; 757 } 758 759 if (cell->enable) { 760 retval = cell->enable(dev); 761 if (retval) 762 goto err_enable; 763 } 764 765 retval = tmiofb_hw_init(dev); 766 if (retval) 767 goto err_hw_init; 768 769 fb_videomode_to_modelist(data->modes, data->num_modes, 770 &info->modelist); 771 772 retval = register_framebuffer(info); 773 if (retval < 0) 774 goto err_register_framebuffer; 775 776 fb_info(info, "%s frame buffer device\n", info->fix.id); 777 778 return 0; 779 780err_register_framebuffer: 781/*err_set_par:*/ 782 tmiofb_hw_stop(dev); 783err_hw_init: 784 if (cell->disable) 785 cell->disable(dev); 786err_enable: 787err_find_mode: 788 free_irq(irq, info); 789err_request_irq: 790 iounmap(info->screen_base); 791err_ioremap_vram: 792 iounmap(par->lcr); 793err_ioremap_lcr: 794 iounmap(par->ccr); 795err_ioremap_ccr: 796 framebuffer_release(info); 797 return retval; 798} 799 800static int tmiofb_remove(struct platform_device *dev) 801{ 802 const struct mfd_cell *cell = mfd_get_cell(dev); 803 struct fb_info *info = platform_get_drvdata(dev); 804 int irq = platform_get_irq(dev, 0); 805 struct tmiofb_par *par; 806 807 if (info) { 808 par = info->par; 809 unregister_framebuffer(info); 810 811 tmiofb_hw_stop(dev); 812 813 if (cell->disable) 814 cell->disable(dev); 815 816 free_irq(irq, info); 817 818 iounmap(info->screen_base); 819 iounmap(par->lcr); 820 iounmap(par->ccr); 821 822 framebuffer_release(info); 823 } 824 825 return 0; 826} 827 828#ifdef DEBUG 829static void tmiofb_dump_regs(struct platform_device *dev) 830{ 831 struct fb_info *info = platform_get_drvdata(dev); 832 struct tmiofb_par *par = info->par; 833 834 printk(KERN_DEBUG "lhccr:\n"); 835#define CCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\ 836 tmio_ioread16(par->ccr + CCR_ ## n)); 837 CCR_PR(CMD); 838 CCR_PR(REVID); 839 CCR_PR(BASEL); 840 CCR_PR(BASEH); 841 CCR_PR(UGCC); 842 CCR_PR(GCC); 843 CCR_PR(USC); 844 CCR_PR(VRAMRTC); 845 CCR_PR(VRAMSAC); 846 CCR_PR(VRAMBC); 847#undef CCR_PR 848 849 printk(KERN_DEBUG "lcr: \n"); 850#define LCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\ 851 tmio_ioread16(par->lcr + LCR_ ## n)); 852 LCR_PR(UIS); 853 LCR_PR(VHPN); 854 LCR_PR(CFSAL); 855 LCR_PR(CFSAH); 856 LCR_PR(CFS); 857 LCR_PR(CFWS); 858 LCR_PR(BBIE); 859 LCR_PR(BBISC); 860 LCR_PR(CCS); 861 LCR_PR(BBES); 862 LCR_PR(CMDL); 863 LCR_PR(CMDH); 864 LCR_PR(CFC); 865 LCR_PR(CCIFC); 866 LCR_PR(HWT); 867 LCR_PR(LCDCCRC); 868 LCR_PR(LCDCC); 869 LCR_PR(LCDCOPC); 870 LCR_PR(LCDIS); 871 LCR_PR(LCDIM); 872 LCR_PR(LCDIE); 873 LCR_PR(GDSAL); 874 LCR_PR(GDSAH); 875 LCR_PR(VHPCL); 876 LCR_PR(VHPCH); 877 LCR_PR(GM); 878 LCR_PR(HT); 879 LCR_PR(HDS); 880 LCR_PR(HSS); 881 LCR_PR(HSE); 882 LCR_PR(HNP); 883 LCR_PR(VT); 884 LCR_PR(VDS); 885 LCR_PR(VSS); 886 LCR_PR(VSE); 887 LCR_PR(CDLN); 888 LCR_PR(ILN); 889 LCR_PR(SP); 890 LCR_PR(MISC); 891 LCR_PR(VIHSS); 892 LCR_PR(VIVS); 893 LCR_PR(VIVE); 894 LCR_PR(VIVSS); 895 LCR_PR(VCCIS); 896 LCR_PR(VIDWSAL); 897 LCR_PR(VIDWSAH); 898 LCR_PR(VIDRSAL); 899 LCR_PR(VIDRSAH); 900 LCR_PR(VIPDDST); 901 LCR_PR(VIPDDET); 902 LCR_PR(VIE); 903 LCR_PR(VCS); 904 LCR_PR(VPHWC); 905 LCR_PR(VPHS); 906 LCR_PR(VPVWC); 907 LCR_PR(VPVS); 908 LCR_PR(PLHPIX); 909 LCR_PR(XS); 910 LCR_PR(XCKHW); 911 LCR_PR(STHS); 912 LCR_PR(VT2); 913 LCR_PR(YCKSW); 914 LCR_PR(YSTS); 915 LCR_PR(PPOLS); 916 LCR_PR(PRECW); 917 LCR_PR(VCLKHW); 918 LCR_PR(OC); 919#undef LCR_PR 920} 921#endif 922 923#ifdef CONFIG_PM 924static int tmiofb_suspend(struct platform_device *dev, pm_message_t state) 925{ 926 struct fb_info *info = platform_get_drvdata(dev); 927#ifdef CONFIG_FB_TMIO_ACCELL 928 struct tmiofb_par *par = info->par; 929#endif 930 const struct mfd_cell *cell = mfd_get_cell(dev); 931 int retval = 0; 932 933 console_lock(); 934 935 fb_set_suspend(info, 1); 936 937 if (info->fbops->fb_sync) 938 info->fbops->fb_sync(info); 939 940 941#ifdef CONFIG_FB_TMIO_ACCELL 942 /* 943 * The fb should be usable even if interrupts are disabled (and they are 944 * during suspend/resume). Switch temporary to forced polling. 945 */ 946 printk(KERN_INFO "tmiofb: switching to polling\n"); 947 par->use_polling = true; 948#endif 949 tmiofb_hw_stop(dev); 950 951 if (cell->suspend) 952 retval = cell->suspend(dev); 953 954 console_unlock(); 955 956 return retval; 957} 958 959static int tmiofb_resume(struct platform_device *dev) 960{ 961 struct fb_info *info = platform_get_drvdata(dev); 962 const struct mfd_cell *cell = mfd_get_cell(dev); 963 int retval = 0; 964 965 console_lock(); 966 967 if (cell->resume) { 968 retval = cell->resume(dev); 969 if (retval) 970 goto out; 971 } 972 973 tmiofb_irq(-1, info); 974 975 tmiofb_hw_init(dev); 976 977 tmiofb_hw_mode(dev); 978 979 fb_set_suspend(info, 0); 980out: 981 console_unlock(); 982 return retval; 983} 984#else 985#define tmiofb_suspend NULL 986#define tmiofb_resume NULL 987#endif 988 989static struct platform_driver tmiofb_driver = { 990 .driver.name = "tmio-fb", 991 .driver.owner = THIS_MODULE, 992 .probe = tmiofb_probe, 993 .remove = tmiofb_remove, 994 .suspend = tmiofb_suspend, 995 .resume = tmiofb_resume, 996}; 997 998/*--------------------------------------------------------------------------*/ 999 1000#ifndef MODULE 1001static void __init tmiofb_setup(char *options) 1002{ 1003 char *this_opt; 1004 1005 if (!options || !*options) 1006 return; 1007 1008 while ((this_opt = strsep(&options, ",")) != NULL) { 1009 if (!*this_opt) 1010 continue; 1011 /* 1012 * FIXME 1013 */ 1014 } 1015} 1016#endif 1017 1018static int __init tmiofb_init(void) 1019{ 1020#ifndef MODULE 1021 char *option = NULL; 1022 1023 if (fb_get_options("tmiofb", &option)) 1024 return -ENODEV; 1025 tmiofb_setup(option); 1026#endif 1027 return platform_driver_register(&tmiofb_driver); 1028} 1029 1030static void __exit tmiofb_cleanup(void) 1031{ 1032 platform_driver_unregister(&tmiofb_driver); 1033} 1034 1035module_init(tmiofb_init); 1036module_exit(tmiofb_cleanup); 1037 1038MODULE_DESCRIPTION("TMIO framebuffer driver"); 1039MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov"); 1040MODULE_LICENSE("GPL");