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

[media] davinci vpbe: OSD(On Screen Display) block

This patch implements the functionality of the OSD block
of the VPBE. The OSD in total supports 4 planes or Video
sources - 2 mainly RGB and 2 Video. The patch implements general
handling of all the planes, with specific emphasis on the Video
plane capabilities as the Video planes are supported through the
V4L2 driver.

Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com>
Acked-by: Muralidharan Karicheri <m-karicheri2@ti.com>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Manjunath Hadli and committed by
Mauro Carvalho Chehab
ff0f23dd 66715cdc

+1989
+1231
drivers/media/video/davinci/vpbe_osd.c
··· 1 + /* 2 + * Copyright (C) 2007-2010 Texas Instruments Inc 3 + * Copyright (C) 2007 MontaVista Software, Inc. 4 + * 5 + * Andy Lowe (alowe@mvista.com), MontaVista Software 6 + * - Initial version 7 + * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd. 8 + * - ported to sub device interface 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation version 2. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * You should have received a copy of the GNU General Public License 20 + * along with this program; if not, write to the Free Software 21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 + * 23 + */ 24 + #include <linux/module.h> 25 + #include <linux/kernel.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/clk.h> 29 + #include <linux/slab.h> 30 + 31 + #include <mach/io.h> 32 + #include <mach/cputype.h> 33 + #include <mach/hardware.h> 34 + 35 + #include <media/davinci/vpss.h> 36 + #include <media/v4l2-device.h> 37 + #include <media/davinci/vpbe_types.h> 38 + #include <media/davinci/vpbe_osd.h> 39 + 40 + #include <linux/io.h> 41 + #include "vpbe_osd_regs.h" 42 + 43 + #define MODULE_NAME VPBE_OSD_SUBDEV_NAME 44 + 45 + /* register access routines */ 46 + static inline u32 osd_read(struct osd_state *sd, u32 offset) 47 + { 48 + struct osd_state *osd = sd; 49 + 50 + return readl(osd->osd_base + offset); 51 + } 52 + 53 + static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset) 54 + { 55 + struct osd_state *osd = sd; 56 + 57 + writel(val, osd->osd_base + offset); 58 + 59 + return val; 60 + } 61 + 62 + static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset) 63 + { 64 + struct osd_state *osd = sd; 65 + 66 + u32 addr = osd->osd_base + offset; 67 + u32 val = readl(addr) | mask; 68 + 69 + writel(val, addr); 70 + 71 + return val; 72 + } 73 + 74 + static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset) 75 + { 76 + struct osd_state *osd = sd; 77 + 78 + u32 addr = osd->osd_base + offset; 79 + u32 val = readl(addr) & ~mask; 80 + 81 + writel(val, addr); 82 + 83 + return val; 84 + } 85 + 86 + static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val, 87 + u32 offset) 88 + { 89 + struct osd_state *osd = sd; 90 + 91 + u32 addr = osd->osd_base + offset; 92 + u32 new_val = (readl(addr) & ~mask) | (val & mask); 93 + 94 + writel(new_val, addr); 95 + 96 + return new_val; 97 + } 98 + 99 + /* define some macros for layer and pixfmt classification */ 100 + #define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1)) 101 + #define is_vid_win(layer) (((layer) == WIN_VID0) || ((layer) == WIN_VID1)) 102 + #define is_rgb_pixfmt(pixfmt) \ 103 + (((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888)) 104 + #define is_yc_pixfmt(pixfmt) \ 105 + (((pixfmt) == PIXFMT_YCbCrI) || ((pixfmt) == PIXFMT_YCrCbI) || \ 106 + ((pixfmt) == PIXFMT_NV12)) 107 + #define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X 108 + #define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5) 109 + 110 + /** 111 + * _osd_dm6446_vid0_pingpong() - field inversion fix for DM6446 112 + * @sd - ptr to struct osd_state 113 + * @field_inversion - inversion flag 114 + * @fb_base_phys - frame buffer address 115 + * @lconfig - ptr to layer config 116 + * 117 + * This routine implements a workaround for the field signal inversion silicon 118 + * erratum described in Advisory 1.3.8 for the DM6446. The fb_base_phys and 119 + * lconfig parameters apply to the vid0 window. This routine should be called 120 + * whenever the vid0 layer configuration or start address is modified, or when 121 + * the OSD field inversion setting is modified. 122 + * Returns: 1 if the ping-pong buffers need to be toggled in the vsync isr, or 123 + * 0 otherwise 124 + */ 125 + static int _osd_dm6446_vid0_pingpong(struct osd_state *sd, 126 + int field_inversion, 127 + unsigned long fb_base_phys, 128 + const struct osd_layer_config *lconfig) 129 + { 130 + struct osd_platform_data *pdata; 131 + 132 + pdata = (struct osd_platform_data *)sd->dev->platform_data; 133 + if (pdata->field_inv_wa_enable) { 134 + 135 + if (!field_inversion || !lconfig->interlaced) { 136 + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); 137 + osd_write(sd, fb_base_phys & ~0x1F, OSD_PPVWIN0ADR); 138 + osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, 0, 139 + OSD_MISCCTL); 140 + return 0; 141 + } else { 142 + unsigned miscctl = OSD_MISCCTL_PPRV; 143 + 144 + osd_write(sd, 145 + (fb_base_phys & ~0x1F) - lconfig->line_length, 146 + OSD_VIDWIN0ADR); 147 + osd_write(sd, 148 + (fb_base_phys & ~0x1F) + lconfig->line_length, 149 + OSD_PPVWIN0ADR); 150 + osd_modify(sd, 151 + OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, miscctl, 152 + OSD_MISCCTL); 153 + 154 + return 1; 155 + } 156 + } 157 + 158 + return 0; 159 + } 160 + 161 + static void _osd_set_field_inversion(struct osd_state *sd, int enable) 162 + { 163 + unsigned fsinv = 0; 164 + 165 + if (enable) 166 + fsinv = OSD_MODE_FSINV; 167 + 168 + osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE); 169 + } 170 + 171 + static void _osd_set_blink_attribute(struct osd_state *sd, int enable, 172 + enum osd_blink_interval blink) 173 + { 174 + u32 osdatrmd = 0; 175 + 176 + if (enable) { 177 + osdatrmd |= OSD_OSDATRMD_BLNK; 178 + osdatrmd |= blink << OSD_OSDATRMD_BLNKINT_SHIFT; 179 + } 180 + /* caller must ensure that OSD1 is configured in attribute mode */ 181 + osd_modify(sd, OSD_OSDATRMD_BLNKINT | OSD_OSDATRMD_BLNK, osdatrmd, 182 + OSD_OSDATRMD); 183 + } 184 + 185 + static void _osd_set_rom_clut(struct osd_state *sd, 186 + enum osd_rom_clut rom_clut) 187 + { 188 + if (rom_clut == ROM_CLUT0) 189 + osd_clear(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL); 190 + else 191 + osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL); 192 + } 193 + 194 + static void _osd_set_palette_map(struct osd_state *sd, 195 + enum osd_win_layer osdwin, 196 + unsigned char pixel_value, 197 + unsigned char clut_index, 198 + enum osd_pix_format pixfmt) 199 + { 200 + static const int map_2bpp[] = { 0, 5, 10, 15 }; 201 + static const int map_1bpp[] = { 0, 15 }; 202 + int bmp_offset; 203 + int bmp_shift; 204 + int bmp_mask; 205 + int bmp_reg; 206 + 207 + switch (pixfmt) { 208 + case PIXFMT_1BPP: 209 + bmp_reg = map_1bpp[pixel_value & 0x1]; 210 + break; 211 + case PIXFMT_2BPP: 212 + bmp_reg = map_2bpp[pixel_value & 0x3]; 213 + break; 214 + case PIXFMT_4BPP: 215 + bmp_reg = pixel_value & 0xf; 216 + break; 217 + default: 218 + return; 219 + } 220 + 221 + switch (osdwin) { 222 + case OSDWIN_OSD0: 223 + bmp_offset = OSD_W0BMP01 + (bmp_reg >> 1) * sizeof(u32); 224 + break; 225 + case OSDWIN_OSD1: 226 + bmp_offset = OSD_W1BMP01 + (bmp_reg >> 1) * sizeof(u32); 227 + break; 228 + default: 229 + return; 230 + } 231 + 232 + if (bmp_reg & 1) { 233 + bmp_shift = 8; 234 + bmp_mask = 0xff << 8; 235 + } else { 236 + bmp_shift = 0; 237 + bmp_mask = 0xff; 238 + } 239 + 240 + osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset); 241 + } 242 + 243 + static void _osd_set_rec601_attenuation(struct osd_state *sd, 244 + enum osd_win_layer osdwin, int enable) 245 + { 246 + switch (osdwin) { 247 + case OSDWIN_OSD0: 248 + osd_modify(sd, OSD_OSDWIN0MD_ATN0E, 249 + enable ? OSD_OSDWIN0MD_ATN0E : 0, 250 + OSD_OSDWIN0MD); 251 + break; 252 + case OSDWIN_OSD1: 253 + osd_modify(sd, OSD_OSDWIN1MD_ATN1E, 254 + enable ? OSD_OSDWIN1MD_ATN1E : 0, 255 + OSD_OSDWIN1MD); 256 + break; 257 + } 258 + } 259 + 260 + static void _osd_set_blending_factor(struct osd_state *sd, 261 + enum osd_win_layer osdwin, 262 + enum osd_blending_factor blend) 263 + { 264 + switch (osdwin) { 265 + case OSDWIN_OSD0: 266 + osd_modify(sd, OSD_OSDWIN0MD_BLND0, 267 + blend << OSD_OSDWIN0MD_BLND0_SHIFT, OSD_OSDWIN0MD); 268 + break; 269 + case OSDWIN_OSD1: 270 + osd_modify(sd, OSD_OSDWIN1MD_BLND1, 271 + blend << OSD_OSDWIN1MD_BLND1_SHIFT, OSD_OSDWIN1MD); 272 + break; 273 + } 274 + } 275 + 276 + static void _osd_enable_color_key(struct osd_state *sd, 277 + enum osd_win_layer osdwin, 278 + unsigned colorkey, 279 + enum osd_pix_format pixfmt) 280 + { 281 + switch (pixfmt) { 282 + case PIXFMT_RGB565: 283 + osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, 284 + OSD_TRANSPVAL); 285 + break; 286 + default: 287 + break; 288 + } 289 + 290 + switch (osdwin) { 291 + case OSDWIN_OSD0: 292 + osd_set(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD); 293 + break; 294 + case OSDWIN_OSD1: 295 + osd_set(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD); 296 + break; 297 + } 298 + } 299 + 300 + static void _osd_disable_color_key(struct osd_state *sd, 301 + enum osd_win_layer osdwin) 302 + { 303 + switch (osdwin) { 304 + case OSDWIN_OSD0: 305 + osd_clear(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD); 306 + break; 307 + case OSDWIN_OSD1: 308 + osd_clear(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD); 309 + break; 310 + } 311 + } 312 + 313 + static void _osd_set_osd_clut(struct osd_state *sd, 314 + enum osd_win_layer osdwin, 315 + enum osd_clut clut) 316 + { 317 + u32 winmd = 0; 318 + 319 + switch (osdwin) { 320 + case OSDWIN_OSD0: 321 + if (clut == RAM_CLUT) 322 + winmd |= OSD_OSDWIN0MD_CLUTS0; 323 + osd_modify(sd, OSD_OSDWIN0MD_CLUTS0, winmd, OSD_OSDWIN0MD); 324 + break; 325 + case OSDWIN_OSD1: 326 + if (clut == RAM_CLUT) 327 + winmd |= OSD_OSDWIN1MD_CLUTS1; 328 + osd_modify(sd, OSD_OSDWIN1MD_CLUTS1, winmd, OSD_OSDWIN1MD); 329 + break; 330 + } 331 + } 332 + 333 + static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer, 334 + enum osd_zoom_factor h_zoom, 335 + enum osd_zoom_factor v_zoom) 336 + { 337 + u32 winmd = 0; 338 + 339 + switch (layer) { 340 + case WIN_OSD0: 341 + winmd |= (h_zoom << OSD_OSDWIN0MD_OHZ0_SHIFT); 342 + winmd |= (v_zoom << OSD_OSDWIN0MD_OVZ0_SHIFT); 343 + osd_modify(sd, OSD_OSDWIN0MD_OHZ0 | OSD_OSDWIN0MD_OVZ0, winmd, 344 + OSD_OSDWIN0MD); 345 + break; 346 + case WIN_VID0: 347 + winmd |= (h_zoom << OSD_VIDWINMD_VHZ0_SHIFT); 348 + winmd |= (v_zoom << OSD_VIDWINMD_VVZ0_SHIFT); 349 + osd_modify(sd, OSD_VIDWINMD_VHZ0 | OSD_VIDWINMD_VVZ0, winmd, 350 + OSD_VIDWINMD); 351 + break; 352 + case WIN_OSD1: 353 + winmd |= (h_zoom << OSD_OSDWIN1MD_OHZ1_SHIFT); 354 + winmd |= (v_zoom << OSD_OSDWIN1MD_OVZ1_SHIFT); 355 + osd_modify(sd, OSD_OSDWIN1MD_OHZ1 | OSD_OSDWIN1MD_OVZ1, winmd, 356 + OSD_OSDWIN1MD); 357 + break; 358 + case WIN_VID1: 359 + winmd |= (h_zoom << OSD_VIDWINMD_VHZ1_SHIFT); 360 + winmd |= (v_zoom << OSD_VIDWINMD_VVZ1_SHIFT); 361 + osd_modify(sd, OSD_VIDWINMD_VHZ1 | OSD_VIDWINMD_VVZ1, winmd, 362 + OSD_VIDWINMD); 363 + break; 364 + } 365 + } 366 + 367 + static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer) 368 + { 369 + switch (layer) { 370 + case WIN_OSD0: 371 + osd_clear(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD); 372 + break; 373 + case WIN_VID0: 374 + osd_clear(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD); 375 + break; 376 + case WIN_OSD1: 377 + /* disable attribute mode as well as disabling the window */ 378 + osd_clear(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1, 379 + OSD_OSDWIN1MD); 380 + break; 381 + case WIN_VID1: 382 + osd_clear(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD); 383 + break; 384 + } 385 + } 386 + 387 + static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer) 388 + { 389 + struct osd_state *osd = sd; 390 + struct osd_window_state *win = &osd->win[layer]; 391 + unsigned long flags; 392 + 393 + spin_lock_irqsave(&osd->lock, flags); 394 + 395 + if (!win->is_enabled) { 396 + spin_unlock_irqrestore(&osd->lock, flags); 397 + return; 398 + } 399 + win->is_enabled = 0; 400 + 401 + _osd_disable_layer(sd, layer); 402 + 403 + spin_unlock_irqrestore(&osd->lock, flags); 404 + } 405 + 406 + static void _osd_enable_attribute_mode(struct osd_state *sd) 407 + { 408 + /* enable attribute mode for OSD1 */ 409 + osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD); 410 + } 411 + 412 + static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer) 413 + { 414 + switch (layer) { 415 + case WIN_OSD0: 416 + osd_set(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD); 417 + break; 418 + case WIN_VID0: 419 + osd_set(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD); 420 + break; 421 + case WIN_OSD1: 422 + /* enable OSD1 and disable attribute mode */ 423 + osd_modify(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1, 424 + OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD); 425 + break; 426 + case WIN_VID1: 427 + osd_set(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD); 428 + break; 429 + } 430 + } 431 + 432 + static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer, 433 + int otherwin) 434 + { 435 + struct osd_state *osd = sd; 436 + struct osd_window_state *win = &osd->win[layer]; 437 + struct osd_layer_config *cfg = &win->lconfig; 438 + unsigned long flags; 439 + 440 + spin_lock_irqsave(&osd->lock, flags); 441 + 442 + /* 443 + * use otherwin flag to know this is the other vid window 444 + * in YUV420 mode, if is, skip this check 445 + */ 446 + if (!otherwin && (!win->is_allocated || 447 + !win->fb_base_phys || 448 + !cfg->line_length || 449 + !cfg->xsize || 450 + !cfg->ysize)) { 451 + spin_unlock_irqrestore(&osd->lock, flags); 452 + return -1; 453 + } 454 + 455 + if (win->is_enabled) { 456 + spin_unlock_irqrestore(&osd->lock, flags); 457 + return 0; 458 + } 459 + win->is_enabled = 1; 460 + 461 + if (cfg->pixfmt != PIXFMT_OSD_ATTR) 462 + _osd_enable_layer(sd, layer); 463 + else { 464 + _osd_enable_attribute_mode(sd); 465 + _osd_set_blink_attribute(sd, osd->is_blinking, osd->blink); 466 + } 467 + 468 + spin_unlock_irqrestore(&osd->lock, flags); 469 + 470 + return 0; 471 + } 472 + 473 + static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer, 474 + unsigned long fb_base_phys, 475 + unsigned long cbcr_ofst) 476 + { 477 + switch (layer) { 478 + case WIN_OSD0: 479 + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); 480 + break; 481 + case WIN_VID0: 482 + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); 483 + break; 484 + case WIN_OSD1: 485 + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); 486 + break; 487 + case WIN_VID1: 488 + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); 489 + break; 490 + } 491 + } 492 + 493 + static void osd_start_layer(struct osd_state *sd, enum osd_layer layer, 494 + unsigned long fb_base_phys, 495 + unsigned long cbcr_ofst) 496 + { 497 + struct osd_state *osd = sd; 498 + struct osd_window_state *win = &osd->win[layer]; 499 + struct osd_layer_config *cfg = &win->lconfig; 500 + unsigned long flags; 501 + 502 + spin_lock_irqsave(&osd->lock, flags); 503 + 504 + win->fb_base_phys = fb_base_phys & ~0x1F; 505 + _osd_start_layer(sd, layer, fb_base_phys, cbcr_ofst); 506 + 507 + if (layer == WIN_VID0) { 508 + osd->pingpong = 509 + _osd_dm6446_vid0_pingpong(sd, osd->field_inversion, 510 + win->fb_base_phys, 511 + cfg); 512 + } 513 + 514 + spin_unlock_irqrestore(&osd->lock, flags); 515 + } 516 + 517 + static void osd_get_layer_config(struct osd_state *sd, enum osd_layer layer, 518 + struct osd_layer_config *lconfig) 519 + { 520 + struct osd_state *osd = sd; 521 + struct osd_window_state *win = &osd->win[layer]; 522 + unsigned long flags; 523 + 524 + spin_lock_irqsave(&osd->lock, flags); 525 + 526 + *lconfig = win->lconfig; 527 + 528 + spin_unlock_irqrestore(&osd->lock, flags); 529 + } 530 + 531 + /** 532 + * try_layer_config() - Try a specific configuration for the layer 533 + * @sd - ptr to struct osd_state 534 + * @layer - layer to configure 535 + * @lconfig - layer configuration to try 536 + * 537 + * If the requested lconfig is completely rejected and the value of lconfig on 538 + * exit is the current lconfig, then try_layer_config() returns 1. Otherwise, 539 + * try_layer_config() returns 0. A return value of 0 does not necessarily mean 540 + * that the value of lconfig on exit is identical to the value of lconfig on 541 + * entry, but merely that it represents a change from the current lconfig. 542 + */ 543 + static int try_layer_config(struct osd_state *sd, enum osd_layer layer, 544 + struct osd_layer_config *lconfig) 545 + { 546 + struct osd_state *osd = sd; 547 + struct osd_window_state *win = &osd->win[layer]; 548 + int bad_config; 549 + 550 + /* verify that the pixel format is compatible with the layer */ 551 + switch (lconfig->pixfmt) { 552 + case PIXFMT_1BPP: 553 + case PIXFMT_2BPP: 554 + case PIXFMT_4BPP: 555 + case PIXFMT_8BPP: 556 + case PIXFMT_RGB565: 557 + bad_config = !is_osd_win(layer); 558 + break; 559 + case PIXFMT_YCbCrI: 560 + case PIXFMT_YCrCbI: 561 + bad_config = !is_vid_win(layer); 562 + break; 563 + case PIXFMT_RGB888: 564 + bad_config = !is_vid_win(layer); 565 + break; 566 + case PIXFMT_NV12: 567 + bad_config = 1; 568 + break; 569 + case PIXFMT_OSD_ATTR: 570 + bad_config = (layer != WIN_OSD1); 571 + break; 572 + default: 573 + bad_config = 1; 574 + break; 575 + } 576 + if (bad_config) { 577 + /* 578 + * The requested pixel format is incompatible with the layer, 579 + * so keep the current layer configuration. 580 + */ 581 + *lconfig = win->lconfig; 582 + return bad_config; 583 + } 584 + 585 + /* DM6446: */ 586 + /* only one OSD window at a time can use RGB pixel formats */ 587 + if (is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { 588 + enum osd_pix_format pixfmt; 589 + if (layer == WIN_OSD0) 590 + pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt; 591 + else 592 + pixfmt = osd->win[WIN_OSD0].lconfig.pixfmt; 593 + 594 + if (is_rgb_pixfmt(pixfmt)) { 595 + /* 596 + * The other OSD window is already configured for an 597 + * RGB, so keep the current layer configuration. 598 + */ 599 + *lconfig = win->lconfig; 600 + return 1; 601 + } 602 + } 603 + 604 + /* DM6446: only one video window at a time can use RGB888 */ 605 + if (is_vid_win(layer) && lconfig->pixfmt == PIXFMT_RGB888) { 606 + enum osd_pix_format pixfmt; 607 + 608 + if (layer == WIN_VID0) 609 + pixfmt = osd->win[WIN_VID1].lconfig.pixfmt; 610 + else 611 + pixfmt = osd->win[WIN_VID0].lconfig.pixfmt; 612 + 613 + if (pixfmt == PIXFMT_RGB888) { 614 + /* 615 + * The other video window is already configured for 616 + * RGB888, so keep the current layer configuration. 617 + */ 618 + *lconfig = win->lconfig; 619 + return 1; 620 + } 621 + } 622 + 623 + /* window dimensions must be non-zero */ 624 + if (!lconfig->line_length || !lconfig->xsize || !lconfig->ysize) { 625 + *lconfig = win->lconfig; 626 + return 1; 627 + } 628 + 629 + /* round line_length up to a multiple of 32 */ 630 + lconfig->line_length = ((lconfig->line_length + 31) / 32) * 32; 631 + lconfig->line_length = 632 + min(lconfig->line_length, (unsigned)MAX_LINE_LENGTH); 633 + lconfig->xsize = min(lconfig->xsize, (unsigned)MAX_WIN_SIZE); 634 + lconfig->ysize = min(lconfig->ysize, (unsigned)MAX_WIN_SIZE); 635 + lconfig->xpos = min(lconfig->xpos, (unsigned)MAX_WIN_SIZE); 636 + lconfig->ypos = min(lconfig->ypos, (unsigned)MAX_WIN_SIZE); 637 + lconfig->interlaced = (lconfig->interlaced != 0); 638 + if (lconfig->interlaced) { 639 + /* ysize and ypos must be even for interlaced displays */ 640 + lconfig->ysize &= ~1; 641 + lconfig->ypos &= ~1; 642 + } 643 + 644 + return 0; 645 + } 646 + 647 + static void _osd_disable_vid_rgb888(struct osd_state *sd) 648 + { 649 + /* 650 + * The DM6446 supports RGB888 pixel format in a single video window. 651 + * This routine disables RGB888 pixel format for both video windows. 652 + * The caller must ensure that neither video window is currently 653 + * configured for RGB888 pixel format. 654 + */ 655 + osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); 656 + } 657 + 658 + static void _osd_enable_vid_rgb888(struct osd_state *sd, 659 + enum osd_layer layer) 660 + { 661 + /* 662 + * The DM6446 supports RGB888 pixel format in a single video window. 663 + * This routine enables RGB888 pixel format for the specified video 664 + * window. The caller must ensure that the other video window is not 665 + * currently configured for RGB888 pixel format, as this routine will 666 + * disable RGB888 pixel format for the other window. 667 + */ 668 + if (layer == WIN_VID0) { 669 + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, 670 + OSD_MISCCTL_RGBEN, OSD_MISCCTL); 671 + } else if (layer == WIN_VID1) { 672 + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, 673 + OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, 674 + OSD_MISCCTL); 675 + } 676 + } 677 + 678 + static void _osd_set_cbcr_order(struct osd_state *sd, 679 + enum osd_pix_format pixfmt) 680 + { 681 + /* 682 + * The caller must ensure that all windows using YC pixfmt use the same 683 + * Cb/Cr order. 684 + */ 685 + if (pixfmt == PIXFMT_YCbCrI) 686 + osd_clear(sd, OSD_MODE_CS, OSD_MODE); 687 + else if (pixfmt == PIXFMT_YCrCbI) 688 + osd_set(sd, OSD_MODE_CS, OSD_MODE); 689 + } 690 + 691 + static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, 692 + const struct osd_layer_config *lconfig) 693 + { 694 + u32 winmd = 0, winmd_mask = 0, bmw = 0; 695 + 696 + _osd_set_cbcr_order(sd, lconfig->pixfmt); 697 + 698 + switch (layer) { 699 + case WIN_OSD0: 700 + winmd_mask |= OSD_OSDWIN0MD_RGB0E; 701 + if (lconfig->pixfmt == PIXFMT_RGB565) 702 + winmd |= OSD_OSDWIN0MD_RGB0E; 703 + 704 + winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0; 705 + 706 + switch (lconfig->pixfmt) { 707 + case PIXFMT_1BPP: 708 + bmw = 0; 709 + break; 710 + case PIXFMT_2BPP: 711 + bmw = 1; 712 + break; 713 + case PIXFMT_4BPP: 714 + bmw = 2; 715 + break; 716 + case PIXFMT_8BPP: 717 + bmw = 3; 718 + break; 719 + default: 720 + break; 721 + } 722 + winmd |= (bmw << OSD_OSDWIN0MD_BMW0_SHIFT); 723 + 724 + if (lconfig->interlaced) 725 + winmd |= OSD_OSDWIN0MD_OFF0; 726 + 727 + osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN0MD); 728 + osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN0OFST); 729 + osd_write(sd, lconfig->xpos, OSD_OSDWIN0XP); 730 + osd_write(sd, lconfig->xsize, OSD_OSDWIN0XL); 731 + if (lconfig->interlaced) { 732 + osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN0YP); 733 + osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN0YL); 734 + } else { 735 + osd_write(sd, lconfig->ypos, OSD_OSDWIN0YP); 736 + osd_write(sd, lconfig->ysize, OSD_OSDWIN0YL); 737 + } 738 + break; 739 + case WIN_VID0: 740 + winmd_mask |= OSD_VIDWINMD_VFF0; 741 + if (lconfig->interlaced) 742 + winmd |= OSD_VIDWINMD_VFF0; 743 + 744 + osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD); 745 + osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN0OFST); 746 + osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP); 747 + osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL); 748 + /* 749 + * For YUV420P format the register contents are 750 + * duplicated in both VID registers 751 + */ 752 + if (lconfig->interlaced) { 753 + osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP); 754 + osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL); 755 + } else { 756 + osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); 757 + osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); 758 + } 759 + break; 760 + case WIN_OSD1: 761 + /* 762 + * The caller must ensure that OSD1 is disabled prior to 763 + * switching from a normal mode to attribute mode or from 764 + * attribute mode to a normal mode. 765 + */ 766 + if (lconfig->pixfmt == PIXFMT_OSD_ATTR) { 767 + winmd_mask |= 768 + OSD_OSDWIN1MD_ATN1E | OSD_OSDWIN1MD_RGB1E | 769 + OSD_OSDWIN1MD_CLUTS1 | 770 + OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; 771 + } else { 772 + winmd_mask |= OSD_OSDWIN1MD_RGB1E; 773 + if (lconfig->pixfmt == PIXFMT_RGB565) 774 + winmd |= OSD_OSDWIN1MD_RGB1E; 775 + 776 + winmd_mask |= OSD_OSDWIN1MD_BMW1; 777 + switch (lconfig->pixfmt) { 778 + case PIXFMT_1BPP: 779 + bmw = 0; 780 + break; 781 + case PIXFMT_2BPP: 782 + bmw = 1; 783 + break; 784 + case PIXFMT_4BPP: 785 + bmw = 2; 786 + break; 787 + case PIXFMT_8BPP: 788 + bmw = 3; 789 + break; 790 + default: 791 + break; 792 + } 793 + winmd |= (bmw << OSD_OSDWIN1MD_BMW1_SHIFT); 794 + } 795 + 796 + winmd_mask |= OSD_OSDWIN1MD_OFF1; 797 + if (lconfig->interlaced) 798 + winmd |= OSD_OSDWIN1MD_OFF1; 799 + 800 + osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN1MD); 801 + osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN1OFST); 802 + osd_write(sd, lconfig->xpos, OSD_OSDWIN1XP); 803 + osd_write(sd, lconfig->xsize, OSD_OSDWIN1XL); 804 + if (lconfig->interlaced) { 805 + osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN1YP); 806 + osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN1YL); 807 + } else { 808 + osd_write(sd, lconfig->ypos, OSD_OSDWIN1YP); 809 + osd_write(sd, lconfig->ysize, OSD_OSDWIN1YL); 810 + } 811 + break; 812 + case WIN_VID1: 813 + winmd_mask |= OSD_VIDWINMD_VFF1; 814 + if (lconfig->interlaced) 815 + winmd |= OSD_VIDWINMD_VFF1; 816 + 817 + osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD); 818 + osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN1OFST); 819 + osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP); 820 + osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL); 821 + /* 822 + * For YUV420P format the register contents are 823 + * duplicated in both VID registers 824 + */ 825 + osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, 826 + OSD_MISCCTL); 827 + 828 + if (lconfig->interlaced) { 829 + osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP); 830 + osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL); 831 + } else { 832 + osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); 833 + osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); 834 + } 835 + break; 836 + } 837 + } 838 + 839 + static int osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, 840 + struct osd_layer_config *lconfig) 841 + { 842 + struct osd_state *osd = sd; 843 + struct osd_window_state *win = &osd->win[layer]; 844 + struct osd_layer_config *cfg = &win->lconfig; 845 + unsigned long flags; 846 + int reject_config; 847 + 848 + spin_lock_irqsave(&osd->lock, flags); 849 + 850 + reject_config = try_layer_config(sd, layer, lconfig); 851 + if (reject_config) { 852 + spin_unlock_irqrestore(&osd->lock, flags); 853 + return reject_config; 854 + } 855 + 856 + /* update the current Cb/Cr order */ 857 + if (is_yc_pixfmt(lconfig->pixfmt)) 858 + osd->yc_pixfmt = lconfig->pixfmt; 859 + 860 + /* 861 + * If we are switching OSD1 from normal mode to attribute mode or from 862 + * attribute mode to normal mode, then we must disable the window. 863 + */ 864 + if (layer == WIN_OSD1) { 865 + if (((lconfig->pixfmt == PIXFMT_OSD_ATTR) && 866 + (cfg->pixfmt != PIXFMT_OSD_ATTR)) || 867 + ((lconfig->pixfmt != PIXFMT_OSD_ATTR) && 868 + (cfg->pixfmt == PIXFMT_OSD_ATTR))) { 869 + win->is_enabled = 0; 870 + _osd_disable_layer(sd, layer); 871 + } 872 + } 873 + 874 + _osd_set_layer_config(sd, layer, lconfig); 875 + 876 + if (layer == WIN_OSD1) { 877 + struct osd_osdwin_state *osdwin_state = 878 + &osd->osdwin[OSDWIN_OSD1]; 879 + 880 + if ((lconfig->pixfmt != PIXFMT_OSD_ATTR) && 881 + (cfg->pixfmt == PIXFMT_OSD_ATTR)) { 882 + /* 883 + * We just switched OSD1 from attribute mode to normal 884 + * mode, so we must initialize the CLUT select, the 885 + * blend factor, transparency colorkey enable, and 886 + * attenuation enable (DM6446 only) bits in the 887 + * OSDWIN1MD register. 888 + */ 889 + _osd_set_osd_clut(sd, OSDWIN_OSD1, 890 + osdwin_state->clut); 891 + _osd_set_blending_factor(sd, OSDWIN_OSD1, 892 + osdwin_state->blend); 893 + if (osdwin_state->colorkey_blending) { 894 + _osd_enable_color_key(sd, OSDWIN_OSD1, 895 + osdwin_state-> 896 + colorkey, 897 + lconfig->pixfmt); 898 + } else 899 + _osd_disable_color_key(sd, OSDWIN_OSD1); 900 + _osd_set_rec601_attenuation(sd, OSDWIN_OSD1, 901 + osdwin_state-> 902 + rec601_attenuation); 903 + } else if ((lconfig->pixfmt == PIXFMT_OSD_ATTR) && 904 + (cfg->pixfmt != PIXFMT_OSD_ATTR)) { 905 + /* 906 + * We just switched OSD1 from normal mode to attribute 907 + * mode, so we must initialize the blink enable and 908 + * blink interval bits in the OSDATRMD register. 909 + */ 910 + _osd_set_blink_attribute(sd, osd->is_blinking, 911 + osd->blink); 912 + } 913 + } 914 + 915 + /* 916 + * If we just switched to a 1-, 2-, or 4-bits-per-pixel bitmap format 917 + * then configure a default palette map. 918 + */ 919 + if ((lconfig->pixfmt != cfg->pixfmt) && 920 + ((lconfig->pixfmt == PIXFMT_1BPP) || 921 + (lconfig->pixfmt == PIXFMT_2BPP) || 922 + (lconfig->pixfmt == PIXFMT_4BPP))) { 923 + enum osd_win_layer osdwin = 924 + ((layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1); 925 + struct osd_osdwin_state *osdwin_state = 926 + &osd->osdwin[osdwin]; 927 + unsigned char clut_index; 928 + unsigned char clut_entries = 0; 929 + 930 + switch (lconfig->pixfmt) { 931 + case PIXFMT_1BPP: 932 + clut_entries = 2; 933 + break; 934 + case PIXFMT_2BPP: 935 + clut_entries = 4; 936 + break; 937 + case PIXFMT_4BPP: 938 + clut_entries = 16; 939 + break; 940 + default: 941 + break; 942 + } 943 + /* 944 + * The default palette map maps the pixel value to the clut 945 + * index, i.e. pixel value 0 maps to clut entry 0, pixel value 946 + * 1 maps to clut entry 1, etc. 947 + */ 948 + for (clut_index = 0; clut_index < 16; clut_index++) { 949 + osdwin_state->palette_map[clut_index] = clut_index; 950 + if (clut_index < clut_entries) { 951 + _osd_set_palette_map(sd, osdwin, clut_index, 952 + clut_index, 953 + lconfig->pixfmt); 954 + } 955 + } 956 + } 957 + 958 + *cfg = *lconfig; 959 + /* DM6446: configure the RGB888 enable and window selection */ 960 + if (osd->win[WIN_VID0].lconfig.pixfmt == PIXFMT_RGB888) 961 + _osd_enable_vid_rgb888(sd, WIN_VID0); 962 + else if (osd->win[WIN_VID1].lconfig.pixfmt == PIXFMT_RGB888) 963 + _osd_enable_vid_rgb888(sd, WIN_VID1); 964 + else 965 + _osd_disable_vid_rgb888(sd); 966 + 967 + if (layer == WIN_VID0) { 968 + osd->pingpong = 969 + _osd_dm6446_vid0_pingpong(sd, osd->field_inversion, 970 + win->fb_base_phys, 971 + cfg); 972 + } 973 + 974 + spin_unlock_irqrestore(&osd->lock, flags); 975 + 976 + return 0; 977 + } 978 + 979 + static void osd_init_layer(struct osd_state *sd, enum osd_layer layer) 980 + { 981 + struct osd_state *osd = sd; 982 + struct osd_window_state *win = &osd->win[layer]; 983 + enum osd_win_layer osdwin; 984 + struct osd_osdwin_state *osdwin_state; 985 + struct osd_layer_config *cfg = &win->lconfig; 986 + unsigned long flags; 987 + 988 + spin_lock_irqsave(&osd->lock, flags); 989 + 990 + win->is_enabled = 0; 991 + _osd_disable_layer(sd, layer); 992 + 993 + win->h_zoom = ZOOM_X1; 994 + win->v_zoom = ZOOM_X1; 995 + _osd_set_zoom(sd, layer, win->h_zoom, win->v_zoom); 996 + 997 + win->fb_base_phys = 0; 998 + _osd_start_layer(sd, layer, win->fb_base_phys, 0); 999 + 1000 + cfg->line_length = 0; 1001 + cfg->xsize = 0; 1002 + cfg->ysize = 0; 1003 + cfg->xpos = 0; 1004 + cfg->ypos = 0; 1005 + cfg->interlaced = 0; 1006 + switch (layer) { 1007 + case WIN_OSD0: 1008 + case WIN_OSD1: 1009 + osdwin = (layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1; 1010 + osdwin_state = &osd->osdwin[osdwin]; 1011 + /* 1012 + * Other code relies on the fact that OSD windows default to a 1013 + * bitmap pixel format when they are deallocated, so don't 1014 + * change this default pixel format. 1015 + */ 1016 + cfg->pixfmt = PIXFMT_8BPP; 1017 + _osd_set_layer_config(sd, layer, cfg); 1018 + osdwin_state->clut = RAM_CLUT; 1019 + _osd_set_osd_clut(sd, osdwin, osdwin_state->clut); 1020 + osdwin_state->colorkey_blending = 0; 1021 + _osd_disable_color_key(sd, osdwin); 1022 + osdwin_state->blend = OSD_8_VID_0; 1023 + _osd_set_blending_factor(sd, osdwin, osdwin_state->blend); 1024 + osdwin_state->rec601_attenuation = 0; 1025 + _osd_set_rec601_attenuation(sd, osdwin, 1026 + osdwin_state-> 1027 + rec601_attenuation); 1028 + if (osdwin == OSDWIN_OSD1) { 1029 + osd->is_blinking = 0; 1030 + osd->blink = BLINK_X1; 1031 + } 1032 + break; 1033 + case WIN_VID0: 1034 + case WIN_VID1: 1035 + cfg->pixfmt = osd->yc_pixfmt; 1036 + _osd_set_layer_config(sd, layer, cfg); 1037 + break; 1038 + } 1039 + 1040 + spin_unlock_irqrestore(&osd->lock, flags); 1041 + } 1042 + 1043 + static void osd_release_layer(struct osd_state *sd, enum osd_layer layer) 1044 + { 1045 + struct osd_state *osd = sd; 1046 + struct osd_window_state *win = &osd->win[layer]; 1047 + unsigned long flags; 1048 + 1049 + spin_lock_irqsave(&osd->lock, flags); 1050 + 1051 + if (!win->is_allocated) { 1052 + spin_unlock_irqrestore(&osd->lock, flags); 1053 + return; 1054 + } 1055 + 1056 + spin_unlock_irqrestore(&osd->lock, flags); 1057 + osd_init_layer(sd, layer); 1058 + spin_lock_irqsave(&osd->lock, flags); 1059 + 1060 + win->is_allocated = 0; 1061 + 1062 + spin_unlock_irqrestore(&osd->lock, flags); 1063 + } 1064 + 1065 + static int osd_request_layer(struct osd_state *sd, enum osd_layer layer) 1066 + { 1067 + struct osd_state *osd = sd; 1068 + struct osd_window_state *win = &osd->win[layer]; 1069 + unsigned long flags; 1070 + 1071 + spin_lock_irqsave(&osd->lock, flags); 1072 + 1073 + if (win->is_allocated) { 1074 + spin_unlock_irqrestore(&osd->lock, flags); 1075 + return -1; 1076 + } 1077 + win->is_allocated = 1; 1078 + 1079 + spin_unlock_irqrestore(&osd->lock, flags); 1080 + 1081 + return 0; 1082 + } 1083 + 1084 + static void _osd_init(struct osd_state *sd) 1085 + { 1086 + osd_write(sd, 0, OSD_MODE); 1087 + osd_write(sd, 0, OSD_VIDWINMD); 1088 + osd_write(sd, 0, OSD_OSDWIN0MD); 1089 + osd_write(sd, 0, OSD_OSDWIN1MD); 1090 + osd_write(sd, 0, OSD_RECTCUR); 1091 + osd_write(sd, 0, OSD_MISCCTL); 1092 + } 1093 + 1094 + static void osd_set_left_margin(struct osd_state *sd, u32 val) 1095 + { 1096 + osd_write(sd, val, OSD_BASEPX); 1097 + } 1098 + 1099 + static void osd_set_top_margin(struct osd_state *sd, u32 val) 1100 + { 1101 + osd_write(sd, val, OSD_BASEPY); 1102 + } 1103 + 1104 + static int osd_initialize(struct osd_state *osd) 1105 + { 1106 + if (osd == NULL) 1107 + return -ENODEV; 1108 + _osd_init(osd); 1109 + 1110 + /* set default Cb/Cr order */ 1111 + osd->yc_pixfmt = PIXFMT_YCbCrI; 1112 + 1113 + _osd_set_field_inversion(osd, osd->field_inversion); 1114 + _osd_set_rom_clut(osd, osd->rom_clut); 1115 + 1116 + osd_init_layer(osd, WIN_OSD0); 1117 + osd_init_layer(osd, WIN_VID0); 1118 + osd_init_layer(osd, WIN_OSD1); 1119 + osd_init_layer(osd, WIN_VID1); 1120 + 1121 + return 0; 1122 + } 1123 + 1124 + static const struct vpbe_osd_ops osd_ops = { 1125 + .initialize = osd_initialize, 1126 + .request_layer = osd_request_layer, 1127 + .release_layer = osd_release_layer, 1128 + .enable_layer = osd_enable_layer, 1129 + .disable_layer = osd_disable_layer, 1130 + .set_layer_config = osd_set_layer_config, 1131 + .get_layer_config = osd_get_layer_config, 1132 + .start_layer = osd_start_layer, 1133 + .set_left_margin = osd_set_left_margin, 1134 + .set_top_margin = osd_set_top_margin, 1135 + }; 1136 + 1137 + static int osd_probe(struct platform_device *pdev) 1138 + { 1139 + struct osd_platform_data *pdata; 1140 + struct osd_state *osd; 1141 + struct resource *res; 1142 + int ret = 0; 1143 + 1144 + osd = kzalloc(sizeof(struct osd_state), GFP_KERNEL); 1145 + if (osd == NULL) 1146 + return -ENOMEM; 1147 + 1148 + osd->dev = &pdev->dev; 1149 + pdata = (struct osd_platform_data *)pdev->dev.platform_data; 1150 + osd->vpbe_type = (enum vpbe_version)pdata->vpbe_type; 1151 + if (NULL == pdev->dev.platform_data) { 1152 + dev_err(osd->dev, "No platform data defined for OSD" 1153 + " sub device\n"); 1154 + ret = -ENOENT; 1155 + goto free_mem; 1156 + } 1157 + 1158 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1159 + if (!res) { 1160 + dev_err(osd->dev, "Unable to get OSD register address map\n"); 1161 + ret = -ENODEV; 1162 + goto free_mem; 1163 + } 1164 + osd->osd_base_phys = res->start; 1165 + osd->osd_size = res->end - res->start + 1; 1166 + if (!request_mem_region(osd->osd_base_phys, osd->osd_size, 1167 + MODULE_NAME)) { 1168 + dev_err(osd->dev, "Unable to reserve OSD MMIO region\n"); 1169 + ret = -ENODEV; 1170 + goto free_mem; 1171 + } 1172 + osd->osd_base = (unsigned long)ioremap_nocache(res->start, 1173 + osd->osd_size); 1174 + if (!osd->osd_base) { 1175 + dev_err(osd->dev, "Unable to map the OSD region\n"); 1176 + ret = -ENODEV; 1177 + goto release_mem_region; 1178 + } 1179 + spin_lock_init(&osd->lock); 1180 + osd->ops = osd_ops; 1181 + platform_set_drvdata(pdev, osd); 1182 + dev_notice(osd->dev, "OSD sub device probe success\n"); 1183 + return ret; 1184 + 1185 + release_mem_region: 1186 + release_mem_region(osd->osd_base_phys, osd->osd_size); 1187 + free_mem: 1188 + kfree(osd); 1189 + return ret; 1190 + } 1191 + 1192 + static int osd_remove(struct platform_device *pdev) 1193 + { 1194 + struct osd_state *osd = platform_get_drvdata(pdev); 1195 + 1196 + iounmap((void *)osd->osd_base); 1197 + release_mem_region(osd->osd_base_phys, osd->osd_size); 1198 + kfree(osd); 1199 + return 0; 1200 + } 1201 + 1202 + static struct platform_driver osd_driver = { 1203 + .probe = osd_probe, 1204 + .remove = osd_remove, 1205 + .driver = { 1206 + .name = MODULE_NAME, 1207 + .owner = THIS_MODULE, 1208 + }, 1209 + }; 1210 + 1211 + static int osd_init(void) 1212 + { 1213 + if (platform_driver_register(&osd_driver)) { 1214 + printk(KERN_ERR "Unable to register davinci osd driver\n"); 1215 + return -ENODEV; 1216 + } 1217 + 1218 + return 0; 1219 + } 1220 + 1221 + static void osd_exit(void) 1222 + { 1223 + platform_driver_unregister(&osd_driver); 1224 + } 1225 + 1226 + module_init(osd_init); 1227 + module_exit(osd_exit); 1228 + 1229 + MODULE_LICENSE("GPL"); 1230 + MODULE_DESCRIPTION("DaVinci OSD Manager Driver"); 1231 + MODULE_AUTHOR("Texas Instruments");
+364
drivers/media/video/davinci/vpbe_osd_regs.h
··· 1 + /* 2 + * Copyright (C) 2006-2010 Texas Instruments Inc 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation version 2. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program; if not, write to the Free Software 15 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 + */ 17 + #ifndef _VPBE_OSD_REGS_H 18 + #define _VPBE_OSD_REGS_H 19 + 20 + /* VPBE Global Registers */ 21 + #define VPBE_PID 0x0 22 + #define VPBE_PCR 0x4 23 + 24 + /* VPSS CLock Registers */ 25 + #define VPSSCLK_PID 0x00 26 + #define VPSSCLK_CLKCTRL 0x04 27 + 28 + /* VPSS Buffer Logic Registers */ 29 + #define VPSSBL_PID 0x00 30 + #define VPSSBL_PCR 0x04 31 + #define VPSSBL_BCR 0x08 32 + #define VPSSBL_INTSTAT 0x0C 33 + #define VPSSBL_INTSEL 0x10 34 + #define VPSSBL_EVTSEL 0x14 35 + #define VPSSBL_MEMCTRL 0x18 36 + #define VPSSBL_CCDCMUX 0x1C 37 + 38 + /* DM365 ISP5 system configuration */ 39 + #define ISP5_PID 0x0 40 + #define ISP5_PCCR 0x4 41 + #define ISP5_BCR 0x8 42 + #define ISP5_INTSTAT 0xC 43 + #define ISP5_INTSEL1 0x10 44 + #define ISP5_INTSEL2 0x14 45 + #define ISP5_INTSEL3 0x18 46 + #define ISP5_EVTSEL 0x1c 47 + #define ISP5_CCDCMUX 0x20 48 + 49 + /* VPBE On-Screen Display Subsystem Registers (OSD) */ 50 + #define OSD_MODE 0x00 51 + #define OSD_VIDWINMD 0x04 52 + #define OSD_OSDWIN0MD 0x08 53 + #define OSD_OSDWIN1MD 0x0C 54 + #define OSD_OSDATRMD 0x0C 55 + #define OSD_RECTCUR 0x10 56 + #define OSD_VIDWIN0OFST 0x18 57 + #define OSD_VIDWIN1OFST 0x1C 58 + #define OSD_OSDWIN0OFST 0x20 59 + #define OSD_OSDWIN1OFST 0x24 60 + #define OSD_VIDWINADH 0x28 61 + #define OSD_VIDWIN0ADL 0x2C 62 + #define OSD_VIDWIN0ADR 0x2C 63 + #define OSD_VIDWIN1ADL 0x30 64 + #define OSD_VIDWIN1ADR 0x30 65 + #define OSD_OSDWINADH 0x34 66 + #define OSD_OSDWIN0ADL 0x38 67 + #define OSD_OSDWIN0ADR 0x38 68 + #define OSD_OSDWIN1ADL 0x3C 69 + #define OSD_OSDWIN1ADR 0x3C 70 + #define OSD_BASEPX 0x40 71 + #define OSD_BASEPY 0x44 72 + #define OSD_VIDWIN0XP 0x48 73 + #define OSD_VIDWIN0YP 0x4C 74 + #define OSD_VIDWIN0XL 0x50 75 + #define OSD_VIDWIN0YL 0x54 76 + #define OSD_VIDWIN1XP 0x58 77 + #define OSD_VIDWIN1YP 0x5C 78 + #define OSD_VIDWIN1XL 0x60 79 + #define OSD_VIDWIN1YL 0x64 80 + #define OSD_OSDWIN0XP 0x68 81 + #define OSD_OSDWIN0YP 0x6C 82 + #define OSD_OSDWIN0XL 0x70 83 + #define OSD_OSDWIN0YL 0x74 84 + #define OSD_OSDWIN1XP 0x78 85 + #define OSD_OSDWIN1YP 0x7C 86 + #define OSD_OSDWIN1XL 0x80 87 + #define OSD_OSDWIN1YL 0x84 88 + #define OSD_CURXP 0x88 89 + #define OSD_CURYP 0x8C 90 + #define OSD_CURXL 0x90 91 + #define OSD_CURYL 0x94 92 + #define OSD_W0BMP01 0xA0 93 + #define OSD_W0BMP23 0xA4 94 + #define OSD_W0BMP45 0xA8 95 + #define OSD_W0BMP67 0xAC 96 + #define OSD_W0BMP89 0xB0 97 + #define OSD_W0BMPAB 0xB4 98 + #define OSD_W0BMPCD 0xB8 99 + #define OSD_W0BMPEF 0xBC 100 + #define OSD_W1BMP01 0xC0 101 + #define OSD_W1BMP23 0xC4 102 + #define OSD_W1BMP45 0xC8 103 + #define OSD_W1BMP67 0xCC 104 + #define OSD_W1BMP89 0xD0 105 + #define OSD_W1BMPAB 0xD4 106 + #define OSD_W1BMPCD 0xD8 107 + #define OSD_W1BMPEF 0xDC 108 + #define OSD_VBNDRY 0xE0 109 + #define OSD_EXTMODE 0xE4 110 + #define OSD_MISCCTL 0xE8 111 + #define OSD_CLUTRAMYCB 0xEC 112 + #define OSD_CLUTRAMCR 0xF0 113 + #define OSD_TRANSPVAL 0xF4 114 + #define OSD_TRANSPVALL 0xF4 115 + #define OSD_TRANSPVALU 0xF8 116 + #define OSD_TRANSPBMPIDX 0xFC 117 + #define OSD_PPVWIN0ADR 0xFC 118 + 119 + /* bit definitions */ 120 + #define VPBE_PCR_VENC_DIV (1 << 1) 121 + #define VPBE_PCR_CLK_OFF (1 << 0) 122 + 123 + #define VPSSBL_INTSTAT_HSSIINT (1 << 14) 124 + #define VPSSBL_INTSTAT_CFALDINT (1 << 13) 125 + #define VPSSBL_INTSTAT_IPIPE_INT5 (1 << 12) 126 + #define VPSSBL_INTSTAT_IPIPE_INT4 (1 << 11) 127 + #define VPSSBL_INTSTAT_IPIPE_INT3 (1 << 10) 128 + #define VPSSBL_INTSTAT_IPIPE_INT2 (1 << 9) 129 + #define VPSSBL_INTSTAT_IPIPE_INT1 (1 << 8) 130 + #define VPSSBL_INTSTAT_IPIPE_INT0 (1 << 7) 131 + #define VPSSBL_INTSTAT_IPIPEIFINT (1 << 6) 132 + #define VPSSBL_INTSTAT_OSDINT (1 << 5) 133 + #define VPSSBL_INTSTAT_VENCINT (1 << 4) 134 + #define VPSSBL_INTSTAT_H3AINT (1 << 3) 135 + #define VPSSBL_INTSTAT_CCDC_VDINT2 (1 << 2) 136 + #define VPSSBL_INTSTAT_CCDC_VDINT1 (1 << 1) 137 + #define VPSSBL_INTSTAT_CCDC_VDINT0 (1 << 0) 138 + 139 + /* DM365 ISP5 bit definitions */ 140 + #define ISP5_INTSTAT_VENCINT (1 << 21) 141 + #define ISP5_INTSTAT_OSDINT (1 << 20) 142 + 143 + /* VMOD TVTYP options for HDMD=0 */ 144 + #define SDTV_NTSC 0 145 + #define SDTV_PAL 1 146 + /* VMOD TVTYP options for HDMD=1 */ 147 + #define HDTV_525P 0 148 + #define HDTV_625P 1 149 + #define HDTV_1080I 2 150 + #define HDTV_720P 3 151 + 152 + #define OSD_MODE_CS (1 << 15) 153 + #define OSD_MODE_OVRSZ (1 << 14) 154 + #define OSD_MODE_OHRSZ (1 << 13) 155 + #define OSD_MODE_EF (1 << 12) 156 + #define OSD_MODE_VVRSZ (1 << 11) 157 + #define OSD_MODE_VHRSZ (1 << 10) 158 + #define OSD_MODE_FSINV (1 << 9) 159 + #define OSD_MODE_BCLUT (1 << 8) 160 + #define OSD_MODE_CABG_SHIFT 0 161 + #define OSD_MODE_CABG (0xff << 0) 162 + 163 + #define OSD_VIDWINMD_VFINV (1 << 15) 164 + #define OSD_VIDWINMD_V1EFC (1 << 14) 165 + #define OSD_VIDWINMD_VHZ1_SHIFT 12 166 + #define OSD_VIDWINMD_VHZ1 (3 << 12) 167 + #define OSD_VIDWINMD_VVZ1_SHIFT 10 168 + #define OSD_VIDWINMD_VVZ1 (3 << 10) 169 + #define OSD_VIDWINMD_VFF1 (1 << 9) 170 + #define OSD_VIDWINMD_ACT1 (1 << 8) 171 + #define OSD_VIDWINMD_V0EFC (1 << 6) 172 + #define OSD_VIDWINMD_VHZ0_SHIFT 4 173 + #define OSD_VIDWINMD_VHZ0 (3 << 4) 174 + #define OSD_VIDWINMD_VVZ0_SHIFT 2 175 + #define OSD_VIDWINMD_VVZ0 (3 << 2) 176 + #define OSD_VIDWINMD_VFF0 (1 << 1) 177 + #define OSD_VIDWINMD_ACT0 (1 << 0) 178 + 179 + #define OSD_OSDWIN0MD_ATN0E (1 << 14) 180 + #define OSD_OSDWIN0MD_RGB0E (1 << 13) 181 + #define OSD_OSDWIN0MD_BMP0MD_SHIFT 13 182 + #define OSD_OSDWIN0MD_BMP0MD (3 << 13) 183 + #define OSD_OSDWIN0MD_CLUTS0 (1 << 12) 184 + #define OSD_OSDWIN0MD_OHZ0_SHIFT 10 185 + #define OSD_OSDWIN0MD_OHZ0 (3 << 10) 186 + #define OSD_OSDWIN0MD_OVZ0_SHIFT 8 187 + #define OSD_OSDWIN0MD_OVZ0 (3 << 8) 188 + #define OSD_OSDWIN0MD_BMW0_SHIFT 6 189 + #define OSD_OSDWIN0MD_BMW0 (3 << 6) 190 + #define OSD_OSDWIN0MD_BLND0_SHIFT 3 191 + #define OSD_OSDWIN0MD_BLND0 (7 << 3) 192 + #define OSD_OSDWIN0MD_TE0 (1 << 2) 193 + #define OSD_OSDWIN0MD_OFF0 (1 << 1) 194 + #define OSD_OSDWIN0MD_OACT0 (1 << 0) 195 + 196 + #define OSD_OSDWIN1MD_OASW (1 << 15) 197 + #define OSD_OSDWIN1MD_ATN1E (1 << 14) 198 + #define OSD_OSDWIN1MD_RGB1E (1 << 13) 199 + #define OSD_OSDWIN1MD_BMP1MD_SHIFT 13 200 + #define OSD_OSDWIN1MD_BMP1MD (3 << 13) 201 + #define OSD_OSDWIN1MD_CLUTS1 (1 << 12) 202 + #define OSD_OSDWIN1MD_OHZ1_SHIFT 10 203 + #define OSD_OSDWIN1MD_OHZ1 (3 << 10) 204 + #define OSD_OSDWIN1MD_OVZ1_SHIFT 8 205 + #define OSD_OSDWIN1MD_OVZ1 (3 << 8) 206 + #define OSD_OSDWIN1MD_BMW1_SHIFT 6 207 + #define OSD_OSDWIN1MD_BMW1 (3 << 6) 208 + #define OSD_OSDWIN1MD_BLND1_SHIFT 3 209 + #define OSD_OSDWIN1MD_BLND1 (7 << 3) 210 + #define OSD_OSDWIN1MD_TE1 (1 << 2) 211 + #define OSD_OSDWIN1MD_OFF1 (1 << 1) 212 + #define OSD_OSDWIN1MD_OACT1 (1 << 0) 213 + 214 + #define OSD_OSDATRMD_OASW (1 << 15) 215 + #define OSD_OSDATRMD_OHZA_SHIFT 10 216 + #define OSD_OSDATRMD_OHZA (3 << 10) 217 + #define OSD_OSDATRMD_OVZA_SHIFT 8 218 + #define OSD_OSDATRMD_OVZA (3 << 8) 219 + #define OSD_OSDATRMD_BLNKINT_SHIFT 6 220 + #define OSD_OSDATRMD_BLNKINT (3 << 6) 221 + #define OSD_OSDATRMD_OFFA (1 << 1) 222 + #define OSD_OSDATRMD_BLNK (1 << 0) 223 + 224 + #define OSD_RECTCUR_RCAD_SHIFT 8 225 + #define OSD_RECTCUR_RCAD (0xff << 8) 226 + #define OSD_RECTCUR_CLUTSR (1 << 7) 227 + #define OSD_RECTCUR_RCHW_SHIFT 4 228 + #define OSD_RECTCUR_RCHW (7 << 4) 229 + #define OSD_RECTCUR_RCVW_SHIFT 1 230 + #define OSD_RECTCUR_RCVW (7 << 1) 231 + #define OSD_RECTCUR_RCACT (1 << 0) 232 + 233 + #define OSD_VIDWIN0OFST_V0LO (0x1ff << 0) 234 + 235 + #define OSD_VIDWIN1OFST_V1LO (0x1ff << 0) 236 + 237 + #define OSD_OSDWIN0OFST_O0LO (0x1ff << 0) 238 + 239 + #define OSD_OSDWIN1OFST_O1LO (0x1ff << 0) 240 + 241 + #define OSD_WINOFST_AH_SHIFT 9 242 + 243 + #define OSD_VIDWIN0OFST_V0AH (0xf << 9) 244 + #define OSD_VIDWIN1OFST_V1AH (0xf << 9) 245 + #define OSD_OSDWIN0OFST_O0AH (0xf << 9) 246 + #define OSD_OSDWIN1OFST_O1AH (0xf << 9) 247 + 248 + #define OSD_VIDWINADH_V1AH_SHIFT 8 249 + #define OSD_VIDWINADH_V1AH (0x7f << 8) 250 + #define OSD_VIDWINADH_V0AH_SHIFT 0 251 + #define OSD_VIDWINADH_V0AH (0x7f << 0) 252 + 253 + #define OSD_VIDWIN0ADL_V0AL (0xffff << 0) 254 + 255 + #define OSD_VIDWIN1ADL_V1AL (0xffff << 0) 256 + 257 + #define OSD_OSDWINADH_O1AH_SHIFT 8 258 + #define OSD_OSDWINADH_O1AH (0x7f << 8) 259 + #define OSD_OSDWINADH_O0AH_SHIFT 0 260 + #define OSD_OSDWINADH_O0AH (0x7f << 0) 261 + 262 + #define OSD_OSDWIN0ADL_O0AL (0xffff << 0) 263 + 264 + #define OSD_OSDWIN1ADL_O1AL (0xffff << 0) 265 + 266 + #define OSD_BASEPX_BPX (0x3ff << 0) 267 + 268 + #define OSD_BASEPY_BPY (0x1ff << 0) 269 + 270 + #define OSD_VIDWIN0XP_V0X (0x7ff << 0) 271 + 272 + #define OSD_VIDWIN0YP_V0Y (0x7ff << 0) 273 + 274 + #define OSD_VIDWIN0XL_V0W (0x7ff << 0) 275 + 276 + #define OSD_VIDWIN0YL_V0H (0x7ff << 0) 277 + 278 + #define OSD_VIDWIN1XP_V1X (0x7ff << 0) 279 + 280 + #define OSD_VIDWIN1YP_V1Y (0x7ff << 0) 281 + 282 + #define OSD_VIDWIN1XL_V1W (0x7ff << 0) 283 + 284 + #define OSD_VIDWIN1YL_V1H (0x7ff << 0) 285 + 286 + #define OSD_OSDWIN0XP_W0X (0x7ff << 0) 287 + 288 + #define OSD_OSDWIN0YP_W0Y (0x7ff << 0) 289 + 290 + #define OSD_OSDWIN0XL_W0W (0x7ff << 0) 291 + 292 + #define OSD_OSDWIN0YL_W0H (0x7ff << 0) 293 + 294 + #define OSD_OSDWIN1XP_W1X (0x7ff << 0) 295 + 296 + #define OSD_OSDWIN1YP_W1Y (0x7ff << 0) 297 + 298 + #define OSD_OSDWIN1XL_W1W (0x7ff << 0) 299 + 300 + #define OSD_OSDWIN1YL_W1H (0x7ff << 0) 301 + 302 + #define OSD_CURXP_RCSX (0x7ff << 0) 303 + 304 + #define OSD_CURYP_RCSY (0x7ff << 0) 305 + 306 + #define OSD_CURXL_RCSW (0x7ff << 0) 307 + 308 + #define OSD_CURYL_RCSH (0x7ff << 0) 309 + 310 + #define OSD_EXTMODE_EXPMDSEL (1 << 15) 311 + #define OSD_EXTMODE_SCRNHEXP_SHIFT 13 312 + #define OSD_EXTMODE_SCRNHEXP (3 << 13) 313 + #define OSD_EXTMODE_SCRNVEXP (1 << 12) 314 + #define OSD_EXTMODE_OSD1BLDCHR (1 << 11) 315 + #define OSD_EXTMODE_OSD0BLDCHR (1 << 10) 316 + #define OSD_EXTMODE_ATNOSD1EN (1 << 9) 317 + #define OSD_EXTMODE_ATNOSD0EN (1 << 8) 318 + #define OSD_EXTMODE_OSDHRSZ15 (1 << 7) 319 + #define OSD_EXTMODE_VIDHRSZ15 (1 << 6) 320 + #define OSD_EXTMODE_ZMFILV1HEN (1 << 5) 321 + #define OSD_EXTMODE_ZMFILV1VEN (1 << 4) 322 + #define OSD_EXTMODE_ZMFILV0HEN (1 << 3) 323 + #define OSD_EXTMODE_ZMFILV0VEN (1 << 2) 324 + #define OSD_EXTMODE_EXPFILHEN (1 << 1) 325 + #define OSD_EXTMODE_EXPFILVEN (1 << 0) 326 + 327 + #define OSD_MISCCTL_BLDSEL (1 << 15) 328 + #define OSD_MISCCTL_S420D (1 << 14) 329 + #define OSD_MISCCTL_BMAPT (1 << 13) 330 + #define OSD_MISCCTL_DM365M (1 << 12) 331 + #define OSD_MISCCTL_RGBEN (1 << 7) 332 + #define OSD_MISCCTL_RGBWIN (1 << 6) 333 + #define OSD_MISCCTL_DMANG (1 << 6) 334 + #define OSD_MISCCTL_TMON (1 << 5) 335 + #define OSD_MISCCTL_RSEL (1 << 4) 336 + #define OSD_MISCCTL_CPBSY (1 << 3) 337 + #define OSD_MISCCTL_PPSW (1 << 2) 338 + #define OSD_MISCCTL_PPRV (1 << 1) 339 + 340 + #define OSD_CLUTRAMYCB_Y_SHIFT 8 341 + #define OSD_CLUTRAMYCB_Y (0xff << 8) 342 + #define OSD_CLUTRAMYCB_CB_SHIFT 0 343 + #define OSD_CLUTRAMYCB_CB (0xff << 0) 344 + 345 + #define OSD_CLUTRAMCR_CR_SHIFT 8 346 + #define OSD_CLUTRAMCR_CR (0xff << 8) 347 + #define OSD_CLUTRAMCR_CADDR_SHIFT 0 348 + #define OSD_CLUTRAMCR_CADDR (0xff << 0) 349 + 350 + #define OSD_TRANSPVAL_RGBTRANS (0xffff << 0) 351 + 352 + #define OSD_TRANSPVALL_RGBL (0xffff << 0) 353 + 354 + #define OSD_TRANSPVALU_Y_SHIFT 8 355 + #define OSD_TRANSPVALU_Y (0xff << 8) 356 + #define OSD_TRANSPVALU_RGBU_SHIFT 0 357 + #define OSD_TRANSPVALU_RGBU (0xff << 0) 358 + 359 + #define OSD_TRANSPBMPIDX_BMP1_SHIFT 8 360 + #define OSD_TRANSPBMPIDX_BMP1 (0xff << 8) 361 + #define OSD_TRANSPBMPIDX_BMP0_SHIFT 0 362 + #define OSD_TRANSPBMPIDX_BMP0 0xff 363 + 364 + #endif /* _DAVINCI_VPBE_H_ */
+394
include/media/davinci/vpbe_osd.h
··· 1 + /* 2 + * Copyright (C) 2007-2009 Texas Instruments Inc 3 + * Copyright (C) 2007 MontaVista Software, Inc. 4 + * 5 + * Andy Lowe (alowe@mvista.com), MontaVista Software 6 + * - Initial version 7 + * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd. 8 + * - ported to sub device interface 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation version 2.. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * You should have received a copy of the GNU General Public License 20 + * along with this program; if not, write to the Free Software 21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 + * 23 + */ 24 + #ifndef _OSD_H 25 + #define _OSD_H 26 + 27 + #include <media/davinci/vpbe_types.h> 28 + 29 + #define VPBE_OSD_SUBDEV_NAME "vpbe-osd" 30 + 31 + /** 32 + * enum osd_layer 33 + * @WIN_OSD0: On-Screen Display Window 0 34 + * @WIN_VID0: Video Window 0 35 + * @WIN_OSD1: On-Screen Display Window 1 36 + * @WIN_VID1: Video Window 1 37 + * 38 + * Description: 39 + * An enumeration of the osd display layers. 40 + */ 41 + enum osd_layer { 42 + WIN_OSD0, 43 + WIN_VID0, 44 + WIN_OSD1, 45 + WIN_VID1, 46 + }; 47 + 48 + /** 49 + * enum osd_win_layer 50 + * @OSDWIN_OSD0: On-Screen Display Window 0 51 + * @OSDWIN_OSD1: On-Screen Display Window 1 52 + * 53 + * Description: 54 + * An enumeration of the OSD Window layers. 55 + */ 56 + enum osd_win_layer { 57 + OSDWIN_OSD0, 58 + OSDWIN_OSD1, 59 + }; 60 + 61 + /** 62 + * enum osd_pix_format 63 + * @PIXFMT_1BPP: 1-bit-per-pixel bitmap 64 + * @PIXFMT_2BPP: 2-bits-per-pixel bitmap 65 + * @PIXFMT_4BPP: 4-bits-per-pixel bitmap 66 + * @PIXFMT_8BPP: 8-bits-per-pixel bitmap 67 + * @PIXFMT_RGB565: 16-bits-per-pixel RGB565 68 + * @PIXFMT_YCbCrI: YUV 4:2:2 69 + * @PIXFMT_RGB888: 24-bits-per-pixel RGB888 70 + * @PIXFMT_YCrCbI: YUV 4:2:2 with chroma swap 71 + * @PIXFMT_NV12: YUV 4:2:0 planar 72 + * @PIXFMT_OSD_ATTR: OSD Attribute Window pixel format (4bpp) 73 + * 74 + * Description: 75 + * An enumeration of the DaVinci pixel formats. 76 + */ 77 + enum osd_pix_format { 78 + PIXFMT_1BPP = 0, 79 + PIXFMT_2BPP, 80 + PIXFMT_4BPP, 81 + PIXFMT_8BPP, 82 + PIXFMT_RGB565, 83 + PIXFMT_YCbCrI, 84 + PIXFMT_RGB888, 85 + PIXFMT_YCrCbI, 86 + PIXFMT_NV12, 87 + PIXFMT_OSD_ATTR, 88 + }; 89 + 90 + /** 91 + * enum osd_h_exp_ratio 92 + * @H_EXP_OFF: no expansion (1/1) 93 + * @H_EXP_9_OVER_8: 9/8 expansion ratio 94 + * @H_EXP_3_OVER_2: 3/2 expansion ratio 95 + * 96 + * Description: 97 + * An enumeration of the available horizontal expansion ratios. 98 + */ 99 + enum osd_h_exp_ratio { 100 + H_EXP_OFF, 101 + H_EXP_9_OVER_8, 102 + H_EXP_3_OVER_2, 103 + }; 104 + 105 + /** 106 + * enum osd_v_exp_ratio 107 + * @V_EXP_OFF: no expansion (1/1) 108 + * @V_EXP_6_OVER_5: 6/5 expansion ratio 109 + * 110 + * Description: 111 + * An enumeration of the available vertical expansion ratios. 112 + */ 113 + enum osd_v_exp_ratio { 114 + V_EXP_OFF, 115 + V_EXP_6_OVER_5, 116 + }; 117 + 118 + /** 119 + * enum osd_zoom_factor 120 + * @ZOOM_X1: no zoom (x1) 121 + * @ZOOM_X2: x2 zoom 122 + * @ZOOM_X4: x4 zoom 123 + * 124 + * Description: 125 + * An enumeration of the available zoom factors. 126 + */ 127 + enum osd_zoom_factor { 128 + ZOOM_X1, 129 + ZOOM_X2, 130 + ZOOM_X4, 131 + }; 132 + 133 + /** 134 + * enum osd_clut 135 + * @ROM_CLUT: ROM CLUT 136 + * @RAM_CLUT: RAM CLUT 137 + * 138 + * Description: 139 + * An enumeration of the available Color Lookup Tables (CLUTs). 140 + */ 141 + enum osd_clut { 142 + ROM_CLUT, 143 + RAM_CLUT, 144 + }; 145 + 146 + /** 147 + * enum osd_rom_clut 148 + * @ROM_CLUT0: Macintosh CLUT 149 + * @ROM_CLUT1: CLUT from DM270 and prior devices 150 + * 151 + * Description: 152 + * An enumeration of the ROM Color Lookup Table (CLUT) options. 153 + */ 154 + enum osd_rom_clut { 155 + ROM_CLUT0, 156 + ROM_CLUT1, 157 + }; 158 + 159 + /** 160 + * enum osd_blending_factor 161 + * @OSD_0_VID_8: OSD pixels are fully transparent 162 + * @OSD_1_VID_7: OSD pixels contribute 1/8, video pixels contribute 7/8 163 + * @OSD_2_VID_6: OSD pixels contribute 2/8, video pixels contribute 6/8 164 + * @OSD_3_VID_5: OSD pixels contribute 3/8, video pixels contribute 5/8 165 + * @OSD_4_VID_4: OSD pixels contribute 4/8, video pixels contribute 4/8 166 + * @OSD_5_VID_3: OSD pixels contribute 5/8, video pixels contribute 3/8 167 + * @OSD_6_VID_2: OSD pixels contribute 6/8, video pixels contribute 2/8 168 + * @OSD_8_VID_0: OSD pixels are fully opaque 169 + * 170 + * Description: 171 + * An enumeration of the DaVinci pixel blending factor options. 172 + */ 173 + enum osd_blending_factor { 174 + OSD_0_VID_8, 175 + OSD_1_VID_7, 176 + OSD_2_VID_6, 177 + OSD_3_VID_5, 178 + OSD_4_VID_4, 179 + OSD_5_VID_3, 180 + OSD_6_VID_2, 181 + OSD_8_VID_0, 182 + }; 183 + 184 + /** 185 + * enum osd_blink_interval 186 + * @BLINK_X1: blink interval is 1 vertical refresh cycle 187 + * @BLINK_X2: blink interval is 2 vertical refresh cycles 188 + * @BLINK_X3: blink interval is 3 vertical refresh cycles 189 + * @BLINK_X4: blink interval is 4 vertical refresh cycles 190 + * 191 + * Description: 192 + * An enumeration of the DaVinci pixel blinking interval options. 193 + */ 194 + enum osd_blink_interval { 195 + BLINK_X1, 196 + BLINK_X2, 197 + BLINK_X3, 198 + BLINK_X4, 199 + }; 200 + 201 + /** 202 + * enum osd_cursor_h_width 203 + * @H_WIDTH_1: horizontal line width is 1 pixel 204 + * @H_WIDTH_4: horizontal line width is 4 pixels 205 + * @H_WIDTH_8: horizontal line width is 8 pixels 206 + * @H_WIDTH_12: horizontal line width is 12 pixels 207 + * @H_WIDTH_16: horizontal line width is 16 pixels 208 + * @H_WIDTH_20: horizontal line width is 20 pixels 209 + * @H_WIDTH_24: horizontal line width is 24 pixels 210 + * @H_WIDTH_28: horizontal line width is 28 pixels 211 + */ 212 + enum osd_cursor_h_width { 213 + H_WIDTH_1, 214 + H_WIDTH_4, 215 + H_WIDTH_8, 216 + H_WIDTH_12, 217 + H_WIDTH_16, 218 + H_WIDTH_20, 219 + H_WIDTH_24, 220 + H_WIDTH_28, 221 + }; 222 + 223 + /** 224 + * enum davinci_cursor_v_width 225 + * @V_WIDTH_1: vertical line width is 1 line 226 + * @V_WIDTH_2: vertical line width is 2 lines 227 + * @V_WIDTH_4: vertical line width is 4 lines 228 + * @V_WIDTH_6: vertical line width is 6 lines 229 + * @V_WIDTH_8: vertical line width is 8 lines 230 + * @V_WIDTH_10: vertical line width is 10 lines 231 + * @V_WIDTH_12: vertical line width is 12 lines 232 + * @V_WIDTH_14: vertical line width is 14 lines 233 + */ 234 + enum osd_cursor_v_width { 235 + V_WIDTH_1, 236 + V_WIDTH_2, 237 + V_WIDTH_4, 238 + V_WIDTH_6, 239 + V_WIDTH_8, 240 + V_WIDTH_10, 241 + V_WIDTH_12, 242 + V_WIDTH_14, 243 + }; 244 + 245 + /** 246 + * struct osd_cursor_config 247 + * @xsize: horizontal size in pixels 248 + * @ysize: vertical size in lines 249 + * @xpos: horizontal offset in pixels from the left edge of the display 250 + * @ypos: vertical offset in lines from the top of the display 251 + * @interlaced: Non-zero if the display is interlaced, or zero otherwise 252 + * @h_width: horizontal line width 253 + * @v_width: vertical line width 254 + * @clut: the CLUT selector (ROM or RAM) for the cursor color 255 + * @clut_index: an index into the CLUT for the cursor color 256 + * 257 + * Description: 258 + * A structure describing the configuration parameters of the hardware 259 + * rectangular cursor. 260 + */ 261 + struct osd_cursor_config { 262 + unsigned xsize; 263 + unsigned ysize; 264 + unsigned xpos; 265 + unsigned ypos; 266 + int interlaced; 267 + enum osd_cursor_h_width h_width; 268 + enum osd_cursor_v_width v_width; 269 + enum osd_clut clut; 270 + unsigned char clut_index; 271 + }; 272 + 273 + /** 274 + * struct osd_layer_config 275 + * @pixfmt: pixel format 276 + * @line_length: offset in bytes between start of each line in memory 277 + * @xsize: number of horizontal pixels displayed per line 278 + * @ysize: number of lines displayed 279 + * @xpos: horizontal offset in pixels from the left edge of the display 280 + * @ypos: vertical offset in lines from the top of the display 281 + * @interlaced: Non-zero if the display is interlaced, or zero otherwise 282 + * 283 + * Description: 284 + * A structure describing the configuration parameters of an On-Screen Display 285 + * (OSD) or video layer related to how the image is stored in memory. 286 + * @line_length must be a multiple of the cache line size (32 bytes). 287 + */ 288 + struct osd_layer_config { 289 + enum osd_pix_format pixfmt; 290 + unsigned line_length; 291 + unsigned xsize; 292 + unsigned ysize; 293 + unsigned xpos; 294 + unsigned ypos; 295 + int interlaced; 296 + }; 297 + 298 + /* parameters that apply on a per-window (OSD or video) basis */ 299 + struct osd_window_state { 300 + int is_allocated; 301 + int is_enabled; 302 + unsigned long fb_base_phys; 303 + enum osd_zoom_factor h_zoom; 304 + enum osd_zoom_factor v_zoom; 305 + struct osd_layer_config lconfig; 306 + }; 307 + 308 + /* parameters that apply on a per-OSD-window basis */ 309 + struct osd_osdwin_state { 310 + enum osd_clut clut; 311 + enum osd_blending_factor blend; 312 + int colorkey_blending; 313 + unsigned colorkey; 314 + int rec601_attenuation; 315 + /* index is pixel value */ 316 + unsigned char palette_map[16]; 317 + }; 318 + 319 + /* hardware rectangular cursor parameters */ 320 + struct osd_cursor_state { 321 + int is_enabled; 322 + struct osd_cursor_config config; 323 + }; 324 + 325 + struct osd_state; 326 + 327 + struct vpbe_osd_ops { 328 + int (*initialize)(struct osd_state *sd); 329 + int (*request_layer)(struct osd_state *sd, enum osd_layer layer); 330 + void (*release_layer)(struct osd_state *sd, enum osd_layer layer); 331 + int (*enable_layer)(struct osd_state *sd, enum osd_layer layer, 332 + int otherwin); 333 + void (*disable_layer)(struct osd_state *sd, enum osd_layer layer); 334 + int (*set_layer_config)(struct osd_state *sd, enum osd_layer layer, 335 + struct osd_layer_config *lconfig); 336 + void (*get_layer_config)(struct osd_state *sd, enum osd_layer layer, 337 + struct osd_layer_config *lconfig); 338 + void (*start_layer)(struct osd_state *sd, enum osd_layer layer, 339 + unsigned long fb_base_phys, 340 + unsigned long cbcr_ofst); 341 + void (*set_left_margin)(struct osd_state *sd, u32 val); 342 + void (*set_top_margin)(struct osd_state *sd, u32 val); 343 + void (*set_interpolation_filter)(struct osd_state *sd, int filter); 344 + int (*set_vid_expansion)(struct osd_state *sd, 345 + enum osd_h_exp_ratio h_exp, 346 + enum osd_v_exp_ratio v_exp); 347 + void (*get_vid_expansion)(struct osd_state *sd, 348 + enum osd_h_exp_ratio *h_exp, 349 + enum osd_v_exp_ratio *v_exp); 350 + void (*set_zoom)(struct osd_state *sd, enum osd_layer layer, 351 + enum osd_zoom_factor h_zoom, 352 + enum osd_zoom_factor v_zoom); 353 + }; 354 + 355 + struct osd_state { 356 + enum vpbe_version vpbe_type; 357 + spinlock_t lock; 358 + struct device *dev; 359 + dma_addr_t osd_base_phys; 360 + unsigned long osd_base; 361 + unsigned long osd_size; 362 + /* 1-->the isr will toggle the VID0 ping-pong buffer */ 363 + int pingpong; 364 + int interpolation_filter; 365 + int field_inversion; 366 + enum osd_h_exp_ratio osd_h_exp; 367 + enum osd_v_exp_ratio osd_v_exp; 368 + enum osd_h_exp_ratio vid_h_exp; 369 + enum osd_v_exp_ratio vid_v_exp; 370 + enum osd_clut backg_clut; 371 + unsigned backg_clut_index; 372 + enum osd_rom_clut rom_clut; 373 + int is_blinking; 374 + /* attribute window blinking enabled */ 375 + enum osd_blink_interval blink; 376 + /* YCbCrI or YCrCbI */ 377 + enum osd_pix_format yc_pixfmt; 378 + /* columns are Y, Cb, Cr */ 379 + unsigned char clut_ram[256][3]; 380 + struct osd_cursor_state cursor; 381 + /* OSD0, VID0, OSD1, VID1 */ 382 + struct osd_window_state win[4]; 383 + /* OSD0, OSD1 */ 384 + struct osd_osdwin_state osdwin[2]; 385 + /* OSD device Operations */ 386 + struct vpbe_osd_ops ops; 387 + }; 388 + 389 + struct osd_platform_data { 390 + enum vpbe_version vpbe_type; 391 + int field_inv_wa_enable; 392 + }; 393 + 394 + #endif