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

[PATCH] mbxfb: Add YUV video overlay support

This patch adds a way to create and use the video plane (YUV overlay) and
scaling video scaling features of the chip.

The overlay is configured, resized and modified using a device specific
ioctl.

Also included in this patch:
- If no platform data was passed, print an error and exit instead of crashing.
- Added a write_reg(_dly) macro. This improves readability when
manipulating chip registers. (no more udelay() after each write).
- Comments about some issues.

Signed-off-by: Raphael Assenat <raph@8d.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Acked-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Raphael Assenat and committed by
Linus Torvalds
ea465250 128806c3

+302 -88
+271 -88
drivers/video/mbx/mbxfb.c
··· 1 1 /* 2 2 * linux/drivers/video/mbx/mbxfb.c 3 3 * 4 + * Copyright (C) 2006 8D Technologies inc 5 + * Raphael Assenat <raph@8d.com> 6 + * - Added video overlay support 7 + * - Various improvements 8 + * 4 9 * Copyright (C) 2006 Compulab, Ltd. 5 10 * Mike Rapoport <mike@compulab.co.il> 11 + * - Creation of driver 6 12 * 7 13 * Based on pxafb.c 8 14 * ··· 25 19 #include <linux/init.h> 26 20 #include <linux/module.h> 27 21 #include <linux/platform_device.h> 22 + #include <linux/uaccess.h> 28 23 29 24 #include <asm/io.h> 30 25 ··· 35 28 #include "reg_bits.h" 36 29 37 30 static unsigned long virt_base_2700; 31 + 32 + #define write_reg(val, reg) do { writel((val), (reg)); } while(0) 33 + 34 + /* Without this delay, the graphics appears somehow scaled and 35 + * there is a lot of jitter in scanlines. This delay is probably 36 + * needed only after setting some specific register(s) somewhere, 37 + * not all over the place... */ 38 + #define write_reg_dly(val, reg) do { writel((val), reg); udelay(1000); } while(0) 38 39 39 40 #define MIN_XRES 16 40 41 #define MIN_YRES 16 ··· 272 257 gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT)); 273 258 gsctrl |= Gsctrl_Width(info->var.xres) | 274 259 Gsctrl_Height(info->var.yres); 275 - writel(gsctrl, GSCTRL); 276 - udelay(1000); 260 + write_reg_dly(gsctrl, GSCTRL); 277 261 278 262 gsadr &= ~(FMsk(GSADR_SRCSTRIDE)); 279 263 gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel / 280 264 (8 * 16) - 1); 281 - writel(gsadr, GSADR); 282 - udelay(1000); 265 + write_reg_dly(gsadr, GSADR); 283 266 284 267 /* setup timings */ 285 268 var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div); 286 269 287 - writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) | 270 + write_reg_dly((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) | 288 271 Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL); 289 272 290 273 hbps = var->hsync_len; ··· 295 282 vfps = vas + var->yres; 296 283 vt = vfps + var->lower_margin; 297 284 298 - writel((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01); 299 - writel((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02); 300 - writel((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03); 301 - writel((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET); 285 + write_reg_dly((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01); 286 + write_reg_dly((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02); 287 + write_reg_dly((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03); 288 + write_reg_dly((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET); 302 289 303 - writel((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01); 304 - writel((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02); 305 - writel((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03); 306 - writel((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET); 307 - writel((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL); 290 + write_reg_dly((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01); 291 + write_reg_dly((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02); 292 + write_reg_dly((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03); 293 + write_reg_dly((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET); 294 + write_reg_dly((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL); 308 295 309 - writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 296 + write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 297 + 298 + write_reg_dly(DINTRE_VEVENT0_EN, DINTRE); 310 299 311 300 return 0; 312 301 } ··· 320 305 case FB_BLANK_VSYNC_SUSPEND: 321 306 case FB_BLANK_HSYNC_SUSPEND: 322 307 case FB_BLANK_NORMAL: 323 - writel((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL); 324 - udelay(1000); 325 - writel((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK); 326 - udelay(1000); 327 - writel((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK); 328 - udelay(1000); 308 + write_reg_dly((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL); 309 + write_reg_dly((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK); 310 + write_reg_dly((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK); 329 311 break; 330 312 case FB_BLANK_UNBLANK: 331 - writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 332 - udelay(1000); 333 - writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK); 334 - udelay(1000); 313 + write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 314 + write_reg_dly((readl(PIXCLK) | PIXCLK_EN), PIXCLK); 335 315 break; 336 316 } 337 317 return 0; 318 + } 319 + 320 + static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) 321 + { 322 + u32 vsctrl, vbbase, vscadr, vsadr; 323 + u32 sssize, spoctrl, svctrl, shctrl; 324 + u32 vubase, vvbase; 325 + u32 vovrclk; 326 + 327 + if (set->scaled_width==0 || set->scaled_height==0) 328 + return -EINVAL; 329 + 330 + /* read registers which have reserved bits 331 + * so we can write them back as-is. */ 332 + vovrclk = readl(VOVRCLK); 333 + vsctrl = readl(VSCTRL); 334 + vscadr = readl(VSCADR); 335 + vubase = readl(VUBASE); 336 + vvbase = readl(VVBASE); 337 + 338 + spoctrl = readl(SPOCTRL); 339 + sssize = readl(SSSIZE); 340 + 341 + 342 + vbbase = Vbbase_Glalpha(set->alpha); 343 + 344 + vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) | 345 + FMsk(VSCTRL_VSHEIGHT) | 346 + FMsk(VSCTRL_VPIXFMT) | 347 + VSCTRL_GAMMA_EN | VSCTRL_CSC_EN | 348 + VSCTRL_COSITED ); 349 + vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) | 350 + VSCTRL_CSC_EN; 351 + 352 + vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC | 353 + FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) | 354 + FMsk(VSCADR_VBASE_ADR) ); 355 + vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR)); 356 + vvbase &= ~(FMsk(VVBASE_VBASE_ADR)); 357 + 358 + switch (set->fmt) 359 + { 360 + case MBXFB_FMT_YUV12: 361 + vsctrl |= VSCTRL_VPIXFMT_YUV12; 362 + 363 + set->Y_stride = ((set->width) + 0xf ) & ~0xf; 364 + 365 + break; 366 + case MBXFB_FMT_UY0VY1: 367 + vsctrl |= VSCTRL_VPIXFMT_UY0VY1; 368 + set->Y_stride = (set->width*2 + 0xf ) & ~0xf; 369 + break; 370 + case MBXFB_FMT_VY0UY1: 371 + vsctrl |= VSCTRL_VPIXFMT_VY0UY1; 372 + set->Y_stride = (set->width*2 + 0xf ) & ~0xf; 373 + break; 374 + case MBXFB_FMT_Y0UY1V: 375 + vsctrl |= VSCTRL_VPIXFMT_Y0UY1V; 376 + set->Y_stride = (set->width*2 + 0xf ) & ~0xf; 377 + break; 378 + case MBXFB_FMT_Y0VY1U: 379 + vsctrl |= VSCTRL_VPIXFMT_Y0VY1U; 380 + set->Y_stride = (set->width*2 + 0xf ) & ~0xf; 381 + break; 382 + default: 383 + return -EINVAL; 384 + } 385 + 386 + /* VSCTRL has the bits which sets the Video Pixel Format. 387 + * When passing from a packed to planar format, 388 + * if we write VSCTRL first, VVBASE and VUBASE would 389 + * be zero if we would not set them here. (And then, 390 + * the chips hangs and only a reset seems to fix it). 391 + * 392 + * If course, the values calculated here have no meaning 393 + * for packed formats. 394 + */ 395 + set->UV_stride = ((set->width/2) + 0x7 ) & ~0x7; 396 + set->U_offset = set->height * set->Y_stride; 397 + set->V_offset = set->U_offset + 398 + set->height * set->UV_stride; 399 + vubase |= Vubase_Ubase_Adr( 400 + (0x60000 + set->mem_offset + set->U_offset)>>3); 401 + vvbase |= Vvbase_Vbase_Adr( 402 + (0x60000 + set->mem_offset + set->V_offset)>>3); 403 + 404 + 405 + vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB | 406 + Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4); 407 + 408 + if (set->enable) 409 + vscadr |= VSCADR_STR_EN; 410 + 411 + 412 + vsadr = Vsadr_Srcstride((set->Y_stride)/16-1) | 413 + Vsadr_Xstart(set->x) | Vsadr_Ystart(set->y); 414 + 415 + sssize &= ~(FMsk(SSSIZE_SC_WIDTH) | FMsk(SSSIZE_SC_HEIGHT)); 416 + sssize = Sssize_Sc_Width(set->scaled_width-1) | 417 + Sssize_Sc_Height(set->scaled_height-1); 418 + 419 + spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | 420 + SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C | 421 + FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH)); 422 + spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height) 423 + | SPOCTRL_VORDER_2TAP; 424 + 425 + /* Bypass horiz/vert scaler when same size */ 426 + if (set->scaled_width == set->width) 427 + spoctrl |= SPOCTRL_H_SC_BP; 428 + if (set->scaled_height == set->height) 429 + spoctrl |= SPOCTRL_V_SC_BP; 430 + 431 + svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10); 432 + 433 + shctrl = Shctrl_Hinitial(4<<11) 434 + | Shctrl_Hpitch((set->width<<11)/set->scaled_width); 435 + 436 + /* Video plane registers */ 437 + write_reg(vsctrl, VSCTRL); 438 + write_reg(vbbase, VBBASE); 439 + write_reg(vscadr, VSCADR); 440 + write_reg(vubase, VUBASE); 441 + write_reg(vvbase, VVBASE); 442 + write_reg(vsadr, VSADR); 443 + 444 + /* Video scaler registers */ 445 + write_reg(sssize, SSSIZE); 446 + write_reg(spoctrl, SPOCTRL); 447 + write_reg(svctrl, SVCTRL); 448 + write_reg(shctrl, SHCTRL); 449 + 450 + /* RAPH: Using those coefficients, the scaled 451 + * image is quite blurry. I dont know how 452 + * to improve them ; The chip documentation 453 + * was not helpful.. */ 454 + write_reg(0x21212121, VSCOEFF0); 455 + write_reg(0x21212121, VSCOEFF1); 456 + write_reg(0x21212121, VSCOEFF2); 457 + write_reg(0x21212121, VSCOEFF3); 458 + write_reg(0x21212121, VSCOEFF4); 459 + write_reg(0x00000000, HSCOEFF0); 460 + write_reg(0x00000000, HSCOEFF1); 461 + write_reg(0x00000000, HSCOEFF2); 462 + write_reg(0x03020201, HSCOEFF3); 463 + write_reg(0x09070604, HSCOEFF4); 464 + write_reg(0x0f0e0c0a, HSCOEFF5); 465 + write_reg(0x15141211, HSCOEFF6); 466 + write_reg(0x19181716, HSCOEFF7); 467 + write_reg(0x00000019, HSCOEFF8); 468 + 469 + /* Clock */ 470 + if (set->enable) 471 + vovrclk |= 1; 472 + else 473 + vovrclk &= ~1; 474 + 475 + write_reg(vovrclk, VOVRCLK); 476 + 477 + return 0; 478 + } 479 + 480 + static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd, 481 + unsigned long arg) 482 + { 483 + struct mbxfb_overlaySetup setup; 484 + int res; 485 + 486 + if (cmd == MBXFB_IOCX_OVERLAY) 487 + { 488 + if (copy_from_user(&setup, (void __user*)arg, 489 + sizeof(struct mbxfb_overlaySetup))) 490 + return -EFAULT; 491 + 492 + res = mbxfb_setupOverlay(&setup); 493 + if (res) 494 + return res; 495 + 496 + if (copy_to_user((void __user*)arg, &setup, 497 + sizeof(struct mbxfb_overlaySetup))) 498 + return -EFAULT; 499 + 500 + return 0; 501 + } 502 + return -EINVAL; 338 503 } 339 504 340 505 static struct fb_ops mbxfb_ops = { ··· 526 331 .fb_copyarea = cfb_copyarea, 527 332 .fb_imageblit = cfb_imageblit, 528 333 .fb_blank = mbxfb_blank, 334 + .fb_ioctl = mbxfb_ioctl, 529 335 }; 530 336 531 337 /* ··· 535 339 */ 536 340 static void __devinit setup_memc(struct fb_info *fbi) 537 341 { 538 - struct mbxfb_info *mfbi = fbi->par; 539 342 unsigned long tmp; 540 343 int i; 541 344 542 345 /* FIXME: use platfrom specific parameters */ 543 346 /* setup SDRAM controller */ 544 - writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | 347 + write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | 545 348 LMCFG_LMA_TS), 546 349 LMCFG); 547 - udelay(1000); 548 350 549 - writel(LMPWR_MC_PWR_ACT, LMPWR); 550 - udelay(1000); 351 + write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); 551 352 552 353 /* setup SDRAM timings */ 553 - writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) | 354 + write_reg_dly((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) | 554 355 Lmtim_Trc(9) | Lmtim_Tdpl(2)), 555 356 LMTIM); 556 - udelay(1000); 557 357 /* setup SDRAM refresh rate */ 558 - writel(0xc2b, LMREFRESH); 559 - udelay(1000); 358 + write_reg_dly(0xc2b, LMREFRESH); 560 359 /* setup SDRAM type parameters */ 561 - writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 | 360 + write_reg_dly((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 | 562 361 LMTYPE_COLSZ_8), 563 362 LMTYPE); 564 - udelay(1000); 565 363 /* enable memory controller */ 566 - writel(LMPWR_MC_PWR_ACT, LMPWR); 567 - udelay(1000); 364 + write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); 568 365 569 366 /* perform dummy reads */ 570 367 for ( i = 0; i < 16; i++ ) { ··· 568 379 static void enable_clocks(struct fb_info *fbi) 569 380 { 570 381 /* enable clocks */ 571 - writel(SYSCLKSRC_PLL_2, SYSCLKSRC); 572 - udelay(1000); 573 - writel(PIXCLKSRC_PLL_1, PIXCLKSRC); 574 - udelay(1000); 575 - writel(0x00000000, CLKSLEEP); 576 - udelay(1000); 577 - writel((Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) | 382 + write_reg_dly(SYSCLKSRC_PLL_2, SYSCLKSRC); 383 + write_reg_dly(PIXCLKSRC_PLL_1, PIXCLKSRC); 384 + write_reg_dly(0x00000000, CLKSLEEP); 385 + 386 + /* PLL output = (Frefclk * M) / (N * 2^P ) 387 + * 388 + * M: 0x17, N: 0x3, P: 0x0 == 100 Mhz! 389 + * M: 0xb, N: 0x1, P: 0x1 == 71 Mhz 390 + * */ 391 + write_reg_dly((Core_Pll_M(0xb) | Core_Pll_N(0x1) | Core_Pll_P(0x1) | 578 392 CORE_PLL_EN), 579 393 COREPLL); 580 - udelay(1000); 581 - writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) | 394 + 395 + write_reg_dly((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) | 582 396 DISP_PLL_EN), 583 397 DISPPLL); 584 398 585 - writel(0x00000000, VOVRCLK); 586 - udelay(1000); 587 - writel(PIXCLK_EN, PIXCLK); 588 - udelay(1000); 589 - writel(MEMCLK_EN, MEMCLK); 590 - udelay(1000); 591 - writel(0x00000006, M24CLK); 592 - udelay(1000); 593 - writel(0x00000006, MBXCLK); 594 - udelay(1000); 595 - writel(SDCLK_EN, SDCLK); 596 - udelay(1000); 597 - writel(0x00000001, PIXCLKDIV); 598 - udelay(1000); 399 + write_reg_dly(0x00000000, VOVRCLK); 400 + write_reg_dly(PIXCLK_EN, PIXCLK); 401 + write_reg_dly(MEMCLK_EN, MEMCLK); 402 + write_reg_dly(0x00000006, M24CLK); 403 + write_reg_dly(0x00000006, MBXCLK); 404 + write_reg_dly(SDCLK_EN, SDCLK); 405 + write_reg_dly(0x00000001, PIXCLKDIV); 599 406 } 600 407 601 408 static void __devinit setup_graphics(struct fb_info *fbi) ··· 615 430 break; 616 431 } 617 432 618 - writel(gsctrl, GSCTRL); 619 - udelay(1000); 620 - writel(0x00000000, GBBASE); 621 - udelay(1000); 622 - writel(0x00ffffff, GDRCTRL); 623 - udelay(1000); 624 - writel((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR); 625 - udelay(1000); 626 - writel(0x00000000, GPLUT); 627 - udelay(1000); 433 + write_reg_dly(gsctrl, GSCTRL); 434 + write_reg_dly(0x00000000, GBBASE); 435 + write_reg_dly(0x00ffffff, GDRCTRL); 436 + write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR); 437 + write_reg_dly(0x00000000, GPLUT); 628 438 } 629 439 630 440 static void __devinit setup_display(struct fb_info *fbi) ··· 631 451 dsctrl |= DSCTRL_HS_POL; 632 452 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) 633 453 dsctrl |= DSCTRL_VS_POL; 634 - writel(dsctrl, DSCTRL); 635 - udelay(1000); 636 - writel(0xd0303010, DMCTRL); 637 - udelay(1000); 638 - writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 454 + write_reg_dly(dsctrl, DSCTRL); 455 + write_reg_dly(0xd0303010, DMCTRL); 456 + write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 639 457 } 640 458 641 459 static void __devinit enable_controller(struct fb_info *fbi) 642 460 { 643 - writel(SYSRST_RST, SYSRST); 644 - udelay(1000); 461 + write_reg_dly(SYSRST_RST, SYSRST); 645 462 646 463 647 464 enable_clocks(fbi); ··· 655 478 static int mbxfb_suspend(struct platform_device *dev, pm_message_t state) 656 479 { 657 480 /* make frame buffer memory enter self-refresh mode */ 658 - writel(LMPWR_MC_PWR_SRM, LMPWR); 481 + write_reg_dly(LMPWR_MC_PWR_SRM, LMPWR); 659 482 while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM) 660 483 ; /* empty statement */ 661 484 662 485 /* reset the device, since it's initial state is 'mostly sleeping' */ 663 - writel(SYSRST_RST, SYSRST); 486 + write_reg_dly(SYSRST_RST, SYSRST); 664 487 return 0; 665 488 } 666 489 ··· 672 495 /* setup_graphics(fbi); */ 673 496 /* setup_display(fbi); */ 674 497 675 - writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 498 + write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 676 499 return 0; 677 500 } 678 501 #else ··· 697 520 698 521 dev_dbg(dev, "mbxfb_probe\n"); 699 522 523 + pdata = dev->dev.platform_data; 524 + if (!pdata) { 525 + dev_err(&dev->dev, "platform data is required\n"); 526 + return -EINVAL; 527 + } 528 + 700 529 fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev); 701 530 if (fbi == NULL) { 702 531 dev_err(&dev->dev, "framebuffer_alloc failed\n"); ··· 711 528 712 529 mfbi = fbi->par; 713 530 fbi->pseudo_palette = mfbi->pseudo_palette; 714 - pdata = dev->dev.platform_data; 531 + 532 + 715 533 if (pdata->probe) 716 534 mfbi->platform_probe = pdata->probe; 717 535 if (pdata->remove) ··· 762 578 goto err4; 763 579 } 764 580 765 - /* FIXME: get from platform */ 766 581 fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000); 767 - fbi->screen_size = 8 * 1024 * 1024; /* 8 Megs */ 582 + fbi->screen_size = pdata->memsize; 768 583 fbi->fbops = &mbxfb_ops; 769 584 770 585 fbi->var = mbxfb_default; 771 586 fbi->fix = mbxfb_fix; 772 587 fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000; 773 - fbi->fix.smem_len = 8 * 1024 * 1024; 774 - fbi->fix.line_length = 640 * 2; 588 + fbi->fix.smem_len = pdata->memsize; 589 + fbi->fix.line_length = mbxfb_default.xres_virtual * 590 + mbxfb_default.bits_per_pixel / 8; 775 591 776 592 ret = fb_alloc_cmap(&fbi->cmap, 256, 0); 777 593 if (ret < 0) { ··· 820 636 { 821 637 struct fb_info *fbi = platform_get_drvdata(dev); 822 638 823 - writel(SYSRST_RST, SYSRST); 824 - udelay(1000); 639 + write_reg_dly(SYSRST_RST, SYSRST); 825 640 826 641 mbxfb_debugfs_remove(fbi); 827 642
+31
include/video/mbxfb.h
··· 1 1 #ifndef __MBX_FB_H 2 2 #define __MBX_FB_H 3 3 4 + #include <asm/ioctl.h> 5 + #include <asm/types.h> 6 + 4 7 struct mbxfb_val { 5 8 unsigned int defval; 6 9 unsigned int min; ··· 27 24 int (*probe)(struct fb_info *fb); 28 25 int (*remove)(struct fb_info *fb); 29 26 }; 27 + 28 + /* planar */ 29 + #define MBXFB_FMT_YUV12 0 30 + 31 + /* packed */ 32 + #define MBXFB_FMT_UY0VY1 1 33 + #define MBXFB_FMT_VY0UY1 2 34 + #define MBXFB_FMT_Y0UY1V 3 35 + #define MBXFB_FMT_Y0VY1U 4 36 + struct mbxfb_overlaySetup { 37 + __u32 enable; 38 + __u32 x, y; 39 + __u32 width, height; 40 + __u32 alpha; 41 + __u32 fmt; 42 + __u32 mem_offset; 43 + __u32 scaled_width; 44 + __u32 scaled_height; 45 + 46 + /* Filled by the driver */ 47 + __u32 U_offset; 48 + __u32 V_offset; 49 + 50 + __u16 Y_stride; 51 + __u16 UV_stride; 52 + }; 53 + 54 + #define MBXFB_IOCX_OVERLAY _IOWR(0xF4, 0x00,struct mbxfb_overlaySetup) 30 55 31 56 #endif /* __MBX_FB_H */