OLD | NEW |
(Empty) | |
| 1 /* linux/drivers/media/video/samsung/tv20/vmixer_s5pv210.c |
| 2 * |
| 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. |
| 4 * http://www.samsung.com/ |
| 5 * |
| 6 * S5PV210 - Mixer raw ftn file for Samsung TVOut driver |
| 7 * |
| 8 * This program is free software; you can redistribute it and/or modify |
| 9 * it under the terms of the GNU General Public License version 2 as |
| 10 * published by the Free Software Foundation. |
| 11 */ |
| 12 |
| 13 #include <linux/module.h> |
| 14 #include <linux/kernel.h> |
| 15 #include <linux/errno.h> |
| 16 #include <linux/string.h> |
| 17 #include <linux/interrupt.h> |
| 18 #include <linux/platform_device.h> |
| 19 #include <linux/clk.h> |
| 20 |
| 21 #include <plat/clock.h> |
| 22 |
| 23 #include <linux/io.h> |
| 24 |
| 25 |
| 26 #include "tv_out_s5pv210.h" |
| 27 |
| 28 #include <mach/regs-vmx.h> |
| 29 |
| 30 #include <linux/irq.h> |
| 31 #include <linux/delay.h> |
| 32 |
| 33 #ifdef CONFIG_TVOUT_RAW_DBG |
| 34 #define S5P_MXR_DEBUG 1 |
| 35 #endif |
| 36 |
| 37 #ifdef S5P_MXR_DEBUG |
| 38 #define VMPRINTK(fmt, args...) \ |
| 39 printk(KERN_INFO "\t\t[VM] %s: " fmt, __func__ , ## args) |
| 40 #else |
| 41 #define VMPRINTK(fmt, args...) |
| 42 #endif |
| 43 |
| 44 static struct resource *mixer_mem; |
| 45 void __iomem *mixer_base; |
| 46 |
| 47 /* |
| 48 *set - set functions are only called under running vmixer |
| 49 */ |
| 50 enum s5p_tv_vmx_err tv_vm_set_layer_show(enum s5p_tv_vmx_layer layer, bool show) |
| 51 { |
| 52 u32 mxr_config; |
| 53 |
| 54 VMPRINTK("%d,%d\n\r", layer, show); |
| 55 |
| 56 switch (layer) { |
| 57 |
| 58 case VM_VIDEO_LAYER: |
| 59 mxr_config = (show) ? |
| 60 (readl(mixer_base + S5P_MXR_CFG) | |
| 61 S5P_MXR_VIDEO_LAYER_SHOW) : |
| 62 (readl(mixer_base + S5P_MXR_CFG) & |
| 63 ~S5P_MXR_VIDEO_LAYER_SHOW); |
| 64 break; |
| 65 |
| 66 case VM_GPR0_LAYER: |
| 67 mxr_config = (show) ? |
| 68 (readl(mixer_base + S5P_MXR_CFG) | |
| 69 S5P_MXR_GRAPHIC0_LAYER_SHOW) : |
| 70 (readl(mixer_base + S5P_MXR_CFG) & |
| 71 ~S5P_MXR_GRAPHIC0_LAYER_SHOW); |
| 72 break; |
| 73 |
| 74 case VM_GPR1_LAYER: |
| 75 mxr_config = (show) ? |
| 76 (readl(mixer_base + S5P_MXR_CFG) | |
| 77 S5P_MXR_GRAPHIC1_LAYER_SHOW) : |
| 78 (readl(mixer_base + S5P_MXR_CFG) & |
| 79 ~S5P_MXR_GRAPHIC1_LAYER_SHOW); |
| 80 break; |
| 81 |
| 82 default: |
| 83 VMPRINTK(" invalid layer parameter = %d\n\r", layer); |
| 84 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 85 } |
| 86 |
| 87 writel(mxr_config, mixer_base + S5P_MXR_CFG); |
| 88 |
| 89 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_CFG)); |
| 90 |
| 91 return VMIXER_NO_ERROR; |
| 92 } |
| 93 |
| 94 enum s5p_tv_vmx_err tv_vm_set_layer_priority(enum s5p_tv_vmx_layer layer, |
| 95 u32 priority) |
| 96 { |
| 97 u32 layer_cfg; |
| 98 |
| 99 VMPRINTK("%d,%d\n\r", layer, priority); |
| 100 |
| 101 switch (layer) { |
| 102 |
| 103 case VM_VIDEO_LAYER: |
| 104 layer_cfg = S5P_MXR_VP_LAYER_PRIORITY_CLEAR(readl( |
| 105 mixer_base + S5P_MXR_LAYER_CFG)) | |
| 106 S5P_MXR_VP_LAYER_PRIORITY(priority); |
| 107 break; |
| 108 |
| 109 case VM_GPR0_LAYER: |
| 110 layer_cfg = S5P_MXR_GRP0_LAYER_PRIORITY_CLEAR( |
| 111 readl(mixer_base + S5P_MXR_LAYER_CFG)) | |
| 112 S5P_MXR_GRP0_LAYER_PRIORITY(priority); |
| 113 break; |
| 114 |
| 115 case VM_GPR1_LAYER: |
| 116 layer_cfg = S5P_MXR_GRP1_LAYER_PRIORITY_CLEAR( |
| 117 readl(mixer_base + S5P_MXR_LAYER_CFG)) | |
| 118 S5P_MXR_GRP1_LAYER_PRIORITY(priority); |
| 119 break; |
| 120 |
| 121 default: |
| 122 VMPRINTK(" invalid layer parameter = %d\n\r", layer); |
| 123 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 124 } |
| 125 |
| 126 writel(layer_cfg, mixer_base + S5P_MXR_LAYER_CFG); |
| 127 |
| 128 return VMIXER_NO_ERROR; |
| 129 } |
| 130 |
| 131 enum s5p_tv_vmx_err tv_vm_set_win_blend(enum s5p_tv_vmx_layer layer, |
| 132 bool enable) |
| 133 { |
| 134 u32 temp_reg; |
| 135 VMPRINTK("%d,%d\n\r", layer, enable); |
| 136 |
| 137 switch (layer) { |
| 138 |
| 139 case VM_VIDEO_LAYER: |
| 140 temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG) |
| 141 & (~S5P_MXR_VP_BLEND_ENABLE) ; |
| 142 |
| 143 if (enable) |
| 144 temp_reg |= S5P_MXR_VP_BLEND_ENABLE; |
| 145 else |
| 146 temp_reg |= S5P_MXR_VP_BLEND_DISABLE; |
| 147 |
| 148 writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); |
| 149 |
| 150 break; |
| 151 |
| 152 case VM_GPR0_LAYER: |
| 153 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG) |
| 154 & (~S5P_MXR_WIN_BLEND_ENABLE) ; |
| 155 |
| 156 if (enable) |
| 157 temp_reg |= S5P_MXR_WIN_BLEND_ENABLE; |
| 158 else |
| 159 temp_reg |= S5P_MXR_WIN_BLEND_DISABLE; |
| 160 |
| 161 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); |
| 162 |
| 163 break; |
| 164 |
| 165 case VM_GPR1_LAYER: |
| 166 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG) |
| 167 & (~S5P_MXR_WIN_BLEND_ENABLE) ; |
| 168 |
| 169 if (enable) |
| 170 temp_reg |= S5P_MXR_WIN_BLEND_ENABLE; |
| 171 else |
| 172 temp_reg |= S5P_MXR_WIN_BLEND_DISABLE; |
| 173 |
| 174 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); |
| 175 |
| 176 break; |
| 177 |
| 178 default: |
| 179 VMPRINTK(" invalid layer parameter = %d\n\r", layer); |
| 180 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 181 } |
| 182 |
| 183 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG)); |
| 184 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); |
| 185 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); |
| 186 |
| 187 return VMIXER_NO_ERROR; |
| 188 } |
| 189 |
| 190 |
| 191 enum s5p_tv_vmx_err tv_vm_set_layer_alpha(enum s5p_tv_vmx_layer layer, |
| 192 u32 alpha) |
| 193 { |
| 194 u32 temp_reg; |
| 195 VMPRINTK("%d,%d\n\r", layer, alpha); |
| 196 |
| 197 switch (layer) { |
| 198 |
| 199 case VM_VIDEO_LAYER: |
| 200 temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG) |
| 201 & (~S5P_MXR_ALPHA) ; |
| 202 temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); |
| 203 writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); |
| 204 break; |
| 205 |
| 206 case VM_GPR0_LAYER: |
| 207 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG) |
| 208 & (~S5P_MXR_ALPHA) ; |
| 209 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); |
| 210 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); |
| 211 break; |
| 212 |
| 213 case VM_GPR1_LAYER: |
| 214 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG) |
| 215 & (~S5P_MXR_ALPHA) ; |
| 216 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); |
| 217 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); |
| 218 break; |
| 219 |
| 220 default: |
| 221 VMPRINTK(" invalid layer parameter = %d\n\r", layer); |
| 222 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 223 } |
| 224 |
| 225 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG)); |
| 226 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); |
| 227 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); |
| 228 |
| 229 return VMIXER_NO_ERROR; |
| 230 } |
| 231 |
| 232 |
| 233 enum s5p_tv_vmx_err tv_vm_set_grp_base_address( |
| 234 enum s5p_tv_vmx_layer layer, u32 base_addr) |
| 235 { |
| 236 VMPRINTK("%d,0x%x\n\r", layer, base_addr); |
| 237 |
| 238 if (S5P_MXR_GRP_ADDR_ILLEGAL(base_addr)) { |
| 239 VMPRINTK(" address is not word align = %d\n\r", base_addr); |
| 240 return S5P_TV_VMX_ERR_BASE_ADDRESS_MUST_WORD_ALIGN; |
| 241 } |
| 242 |
| 243 switch (layer) { |
| 244 |
| 245 case VM_GPR0_LAYER: |
| 246 writel(S5P_MXR_GPR_BASE(base_addr), |
| 247 mixer_base + S5P_MXR_GRAPHIC0_BASE); |
| 248 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_BASE)); |
| 249 break; |
| 250 |
| 251 case VM_GPR1_LAYER: |
| 252 writel(S5P_MXR_GPR_BASE(base_addr), |
| 253 mixer_base + S5P_MXR_GRAPHIC1_BASE); |
| 254 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_BASE)); |
| 255 break; |
| 256 |
| 257 default: |
| 258 VMPRINTK(" invalid layer parameter = %d\n\r", layer); |
| 259 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 260 } |
| 261 |
| 262 return VMIXER_NO_ERROR; |
| 263 } |
| 264 |
| 265 enum s5p_tv_vmx_err tv_vm_set_grp_layer_position(enum s5p_tv_vmx_layer layer, |
| 266 u32 dst_offs_x, u32 dst_offs_y) |
| 267 { |
| 268 VMPRINTK("%d,%d,%d)\n\r", layer, dst_offs_x, dst_offs_y); |
| 269 |
| 270 switch (layer) { |
| 271 |
| 272 case VM_GPR0_LAYER: |
| 273 writel(S5P_MXR_GRP_DESTX(dst_offs_x) | |
| 274 S5P_MXR_GRP_DESTY(dst_offs_y), |
| 275 mixer_base + S5P_MXR_GRAPHIC0_DXY); |
| 276 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_DXY)); |
| 277 break; |
| 278 |
| 279 case VM_GPR1_LAYER: |
| 280 writel(S5P_MXR_GRP_DESTX(dst_offs_x) | |
| 281 S5P_MXR_GRP_DESTY(dst_offs_y), |
| 282 mixer_base + S5P_MXR_GRAPHIC1_DXY); |
| 283 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_DXY)); |
| 284 break; |
| 285 |
| 286 default: |
| 287 VMPRINTK("invalid layer parameter = %d\n\r", layer); |
| 288 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 289 } |
| 290 |
| 291 return VMIXER_NO_ERROR; |
| 292 } |
| 293 |
| 294 enum s5p_tv_vmx_err tv_vm_set_grp_layer_size(enum s5p_tv_vmx_layer layer, |
| 295 u32 span, |
| 296 u32 width, |
| 297 u32 height, |
| 298 u32 src_offs_x, |
| 299 u32 src_offs_y) |
| 300 { |
| 301 VMPRINTK("%d,%d,%d,%d,%d,%d)\n\r", layer, span, width, height, |
| 302 src_offs_x, src_offs_y); |
| 303 |
| 304 switch (layer) { |
| 305 |
| 306 case VM_GPR0_LAYER: |
| 307 writel(S5P_MXR_GRP_SPAN(span), |
| 308 mixer_base + S5P_MXR_GRAPHIC0_SPAN); |
| 309 writel(S5P_MXR_GRP_WIDTH(width) | S5P_MXR_GRP_HEIGHT(height), |
| 310 mixer_base + S5P_MXR_GRAPHIC0_WH); |
| 311 writel(S5P_MXR_GRP_STARTX(src_offs_x) | |
| 312 S5P_MXR_GRP_STARTY(src_offs_y), |
| 313 mixer_base + S5P_MXR_GRAPHIC0_SXY); |
| 314 VMPRINTK("0x%x,0x%x,0x%x\n\r", |
| 315 readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN), |
| 316 readl(mixer_base + S5P_MXR_GRAPHIC0_WH), |
| 317 readl(mixer_base + S5P_MXR_GRAPHIC0_SXY)); |
| 318 break; |
| 319 |
| 320 case VM_GPR1_LAYER: |
| 321 writel(S5P_MXR_GRP_SPAN(span), |
| 322 mixer_base + S5P_MXR_GRAPHIC1_SPAN); |
| 323 writel(S5P_MXR_GRP_WIDTH(width) | S5P_MXR_GRP_HEIGHT(height), |
| 324 mixer_base + S5P_MXR_GRAPHIC1_WH); |
| 325 writel(S5P_MXR_GRP_STARTX(src_offs_x) | |
| 326 S5P_MXR_GRP_STARTY(src_offs_y), |
| 327 mixer_base + S5P_MXR_GRAPHIC1_SXY); |
| 328 VMPRINTK("0x%x,0x%x,0x%x\n\r", |
| 329 readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN), |
| 330 readl(mixer_base + S5P_MXR_GRAPHIC1_WH), |
| 331 readl(mixer_base + S5P_MXR_GRAPHIC1_SXY)); |
| 332 break; |
| 333 |
| 334 default: |
| 335 VMPRINTK(" invalid layer parameter = %d\n\r", layer); |
| 336 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 337 } |
| 338 |
| 339 return VMIXER_NO_ERROR; |
| 340 } |
| 341 |
| 342 enum s5p_tv_vmx_err tv_vm_set_bg_color(enum s5p_tv_vmx_bg_color_num colornum, |
| 343 u32 color_y, |
| 344 u32 color_cb, |
| 345 u32 color_cr) |
| 346 { |
| 347 u32 reg_value; |
| 348 VMPRINTK("%d,%d,%d,%d)\n\r", colornum, color_y, color_cb, color_cr); |
| 349 |
| 350 reg_value = S5P_MXR_BG_COLOR_Y(color_y) | |
| 351 S5P_MXR_BG_COLOR_CB(color_cb) | S5P_MXR_BG_COLOR_CR(color_cr); |
| 352 |
| 353 switch (colornum) { |
| 354 |
| 355 case VMIXER_BG_COLOR_0: |
| 356 writel(reg_value, mixer_base + S5P_MXR_BG_COLOR0); |
| 357 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR0)); |
| 358 break; |
| 359 |
| 360 case VMIXER_BG_COLOR_1: |
| 361 writel(reg_value, mixer_base + S5P_MXR_BG_COLOR1); |
| 362 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR1)); |
| 363 break; |
| 364 |
| 365 case VMIXER_BG_COLOR_2: |
| 366 writel(reg_value, mixer_base + S5P_MXR_BG_COLOR2); |
| 367 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR2)); |
| 368 break; |
| 369 |
| 370 default: |
| 371 VMPRINTK(" invalid uiColorNum parameter = %d\n\r", colornum); |
| 372 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 373 } |
| 374 |
| 375 return VMIXER_NO_ERROR; |
| 376 } |
| 377 |
| 378 /* |
| 379 * initialization - iniization functions are only called under stopping vmixer |
| 380 */ |
| 381 enum s5p_tv_vmx_err tv_vm_init_status_reg( |
| 382 enum s5p_vmx_burst_mode burst, enum s5p_endian_type endian) |
| 383 { |
| 384 u32 temp_reg = 0; |
| 385 |
| 386 VMPRINTK("++(%d,%d)\n\r", burst, endian); |
| 387 |
| 388 temp_reg = S5P_MXR_MIXER_RESERVED | S5P_MXR_CMU_CANNOT_STOP_CLOCK; |
| 389 |
| 390 switch (burst) { |
| 391 |
| 392 case VM_BURST_8: |
| 393 temp_reg |= S5P_MXR_BURST8_MODE; |
| 394 break; |
| 395 |
| 396 case VM_BURST_16: |
| 397 temp_reg |= S5P_MXR_BURST16_MODE; |
| 398 break; |
| 399 |
| 400 default: |
| 401 VMPRINTK("[ERR] : invalid burst parameter = %d\n\r", burst); |
| 402 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 403 } |
| 404 |
| 405 switch (endian) { |
| 406 |
| 407 case TVOUT_BIG_ENDIAN_MODE: |
| 408 temp_reg |= S5P_MXR_BIG_ENDIAN_SOURCE_FORMAT; |
| 409 break; |
| 410 |
| 411 case TVOUT_LITTLE_ENDIAN_MODE: |
| 412 temp_reg |= S5P_MXR_LITTLE_ENDIAN_SOURCE_FORMAT; |
| 413 break; |
| 414 |
| 415 default: |
| 416 VMPRINTK("[ERR] : invalid endian parameter = %d\n\r", endian); |
| 417 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 418 } |
| 419 |
| 420 writel(temp_reg, mixer_base + S5P_MXR_STATUS); |
| 421 |
| 422 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_STATUS)); |
| 423 |
| 424 return VMIXER_NO_ERROR; |
| 425 } |
| 426 |
| 427 enum s5p_tv_vmx_err tv_vm_init_display_mode( |
| 428 enum s5p_tv_disp_mode mode, enum s5p_tv_o_mode output_mode) |
| 429 { |
| 430 u32 temp_reg = readl(mixer_base + S5P_MXR_CFG); |
| 431 |
| 432 VMPRINTK("%d,%d)\n\r", mode, output_mode); |
| 433 |
| 434 switch (mode) { |
| 435 |
| 436 case TVOUT_NTSC_M: |
| 437 case TVOUT_NTSC_443: |
| 438 temp_reg &= ~S5P_MXR_HD; |
| 439 temp_reg &= ~S5P_MXR_PAL; |
| 440 temp_reg &= S5P_MXR_INTERLACE_MODE; |
| 441 break; |
| 442 |
| 443 case TVOUT_PAL_BDGHI: |
| 444 case TVOUT_PAL_M: |
| 445 case TVOUT_PAL_N: |
| 446 case TVOUT_PAL_NC: |
| 447 case TVOUT_PAL_60: |
| 448 temp_reg &= ~S5P_MXR_HD; |
| 449 temp_reg |= S5P_MXR_PAL; |
| 450 temp_reg &= S5P_MXR_INTERLACE_MODE; |
| 451 break; |
| 452 |
| 453 case TVOUT_480P_60_16_9: |
| 454 case TVOUT_480P_60_4_3: |
| 455 case TVOUT_480P_59: |
| 456 temp_reg &= ~S5P_MXR_HD; |
| 457 temp_reg &= ~S5P_MXR_PAL; |
| 458 temp_reg |= S5P_MXR_PROGRESSVE_MODE; |
| 459 break; |
| 460 |
| 461 case TVOUT_576P_50_16_9: |
| 462 case TVOUT_576P_50_4_3: |
| 463 temp_reg &= ~S5P_MXR_HD; |
| 464 temp_reg |= S5P_MXR_PAL; |
| 465 temp_reg |= S5P_MXR_PROGRESSVE_MODE; |
| 466 break; |
| 467 |
| 468 case TVOUT_720P_50: |
| 469 case TVOUT_720P_59: |
| 470 case TVOUT_720P_60: |
| 471 temp_reg |= S5P_MXR_HD; |
| 472 temp_reg &= ~S5P_MXR_HD_1080I_MODE; |
| 473 temp_reg |= S5P_MXR_PROGRESSVE_MODE; |
| 474 break; |
| 475 |
| 476 case TVOUT_1080I_50: |
| 477 case TVOUT_1080I_59: |
| 478 case TVOUT_1080I_60: |
| 479 temp_reg |= S5P_MXR_HD; |
| 480 temp_reg |= S5P_MXR_HD_1080I_MODE; |
| 481 temp_reg &= S5P_MXR_INTERLACE_MODE; |
| 482 break; |
| 483 |
| 484 case TVOUT_1080P_50: |
| 485 case TVOUT_1080P_59: |
| 486 case TVOUT_1080P_60: |
| 487 case TVOUT_1080P_30: |
| 488 temp_reg |= S5P_MXR_HD; |
| 489 temp_reg |= S5P_MXR_HD_1080P_MODE; |
| 490 temp_reg |= S5P_MXR_PROGRESSVE_MODE; |
| 491 break; |
| 492 |
| 493 default: |
| 494 VMPRINTK(" invalid mode parameter = %d\n\r", mode); |
| 495 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 496 } |
| 497 |
| 498 switch (output_mode) { |
| 499 |
| 500 case TVOUT_OUTPUT_COMPOSITE: |
| 501 case TVOUT_OUTPUT_SVIDEO: |
| 502 case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED: |
| 503 case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE: |
| 504 case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE: |
| 505 temp_reg &= S5P_MXR_DST_SEL_ANALOG; |
| 506 break; |
| 507 |
| 508 case TVOUT_OUTPUT_HDMI_RGB: |
| 509 case TVOUT_OUTPUT_DVI: |
| 510 temp_reg |= S5P_MXR_DST_SEL_HDMI; |
| 511 temp_reg &= ~(0x7<<8); |
| 512 temp_reg |= RGB709_16_235<<9 | MX_RGB888<<8; |
| 513 break; |
| 514 |
| 515 case TVOUT_OUTPUT_HDMI: |
| 516 temp_reg |= S5P_MXR_DST_SEL_HDMI; |
| 517 temp_reg &= ~(0x7<<8); |
| 518 temp_reg |= RGB601_16_235<<9 | MX_YUV444<<8; |
| 519 break; |
| 520 |
| 521 default: |
| 522 VMPRINTK(" invalid mode parameter = %d\n\r", mode); |
| 523 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 524 } |
| 525 |
| 526 writel(temp_reg, mixer_base + S5P_MXR_CFG); |
| 527 |
| 528 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CFG)); |
| 529 |
| 530 return VMIXER_NO_ERROR; |
| 531 } |
| 532 |
| 533 u32 grp_scaling_factor(u32 src, u32 dst, u32 h_v) |
| 534 { |
| 535 u32 factor; /* for scaling factor */ |
| 536 |
| 537 /* check scale or not */ |
| 538 if (src == dst) |
| 539 factor = 0; |
| 540 |
| 541 if (dst % src) { |
| 542 factor = 0; |
| 543 |
| 544 VMPRINTK(" can't %s scaling src(%d) into dst(%d)\n" |
| 545 , h_v ? "horizontal" : "vertical" |
| 546 , src_w, dst_w); |
| 547 VMPRINTK(" scaling vector must be 2/4/8x\n"); |
| 548 } |
| 549 |
| 550 factor = dst / src; |
| 551 |
| 552 switch (factor) { |
| 553 case 2: |
| 554 factor = 1; |
| 555 break; |
| 556 |
| 557 case 4: |
| 558 factor = 2; |
| 559 break; |
| 560 |
| 561 case 8: |
| 562 factor = 3; |
| 563 break; |
| 564 |
| 565 default: |
| 566 VMPRINTK(" scaling vector must be 2/4/8x\n"); |
| 567 factor = 0; |
| 568 break; |
| 569 } |
| 570 |
| 571 return factor; |
| 572 } |
| 573 |
| 574 void tv_vm_set_ctrl(enum s5p_tv_vmx_layer layer, |
| 575 bool premul, |
| 576 bool pixel_blending, |
| 577 bool blank_change, |
| 578 bool win_blending, |
| 579 enum s5p_tv_vmx_color_fmt color, |
| 580 u32 alpha, u32 blank_color) |
| 581 { |
| 582 u32 reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG); |
| 583 |
| 584 if (blank_change) |
| 585 reg &= ~S5P_MXR_BLANK_CHANGE_NEW_PIXEL; |
| 586 else |
| 587 reg |= S5P_MXR_BLANK_CHANGE_NEW_PIXEL; |
| 588 |
| 589 |
| 590 if (premul) |
| 591 reg |= S5P_MXR_PRE_MUL_MODE; |
| 592 else |
| 593 reg &= ~S5P_MXR_PRE_MUL_MODE; |
| 594 |
| 595 if (win_blending) |
| 596 reg |= S5P_MXR_WIN_BLEND_ENABLE; |
| 597 else |
| 598 reg &= ~S5P_MXR_WIN_BLEND_ENABLE; |
| 599 |
| 600 reg &= ~S5P_MXR_EG_COLOR_FORMAT(VM_DIRECT_RGB8888); |
| 601 reg |= S5P_MXR_EG_COLOR_FORMAT(color); |
| 602 |
| 603 reg &= ~S5P_MXR_GRP_ALPHA_VALUE(0xff); |
| 604 reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); |
| 605 |
| 606 writel(reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); |
| 607 writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), |
| 608 mixer_base + S5P_MXR_GRAPHIC0_BLANK); |
| 609 |
| 610 } |
| 611 |
| 612 enum s5p_tv_vmx_err tv_vm_init_layer(enum s5p_tv_disp_mode mode, |
| 613 enum s5p_tv_vmx_layer layer, |
| 614 bool show, |
| 615 bool win_blending, |
| 616 u32 alpha, |
| 617 u32 priority, |
| 618 enum s5p_tv_vmx_color_fmt color, |
| 619 bool blank_change, |
| 620 bool pixel_blending, |
| 621 bool premul, |
| 622 u32 blank_color, |
| 623 u32 base_addr, |
| 624 u32 span, |
| 625 u32 width, |
| 626 u32 height, |
| 627 u32 src_offs_x, |
| 628 u32 src_offs_y, |
| 629 u32 dst_offs_x, |
| 630 u32 dst_offs_y, |
| 631 u32 dst_width, |
| 632 u32 dst_height) |
| 633 { |
| 634 u32 temp_reg = 0; |
| 635 u32 h_factor = 0, v_factor = 0; |
| 636 |
| 637 VMPRINTK("%d,%d,%d,%d,%d,%d,%d,%d,%d,0x%x,0x%x,%d,%d, \ |
| 638 %d,%d,%d,%d,%d)\n\r", |
| 639 layer, show, win_blending, alpha, priority, color, |
| 640 blank_change, pixel_blending, premul, blank_color, |
| 641 base_addr, span, width, height, src_offs_x, src_offs_y, |
| 642 dst_offs_x, dst_offs_y); |
| 643 |
| 644 switch (layer) { |
| 645 |
| 646 case VM_VIDEO_LAYER: |
| 647 temp_reg = (win_blending) ? |
| 648 S5P_MXR_VP_BLEND_ENABLE : S5P_MXR_VP_BLEND_DISABLE; |
| 649 temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha); |
| 650 /* temp yuv pxl limiter setting*/ |
| 651 temp_reg &= ~(1<<17); |
| 652 writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG); |
| 653 break; |
| 654 |
| 655 case VM_GPR0_LAYER: |
| 656 temp_reg = (blank_change) ? S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : |
| 657 S5P_MXR_BLANK_CHANGE_NEW_PIXEL; |
| 658 temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE : |
| 659 S5P_MXR_NORMAL_MODE; |
| 660 temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : |
| 661 S5P_MXR_WIN_BLEND_DISABLE; |
| 662 temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : |
| 663 S5P_MXR_PIXEL_BLEND_DISABLE; |
| 664 temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); |
| 665 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); |
| 666 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG); |
| 667 writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), |
| 668 mixer_base + S5P_MXR_GRAPHIC0_BLANK); |
| 669 |
| 670 VMPRINTK("--(0x%x)\n\r", |
| 671 readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); |
| 672 VMPRINTK("--(0x%x)\n\r", |
| 673 readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); |
| 674 |
| 675 tv_vm_set_grp_layer_size(layer, span, width, height, |
| 676 src_offs_x, src_offs_y); |
| 677 |
| 678 tv_vm_set_grp_base_address(layer, base_addr); |
| 679 tv_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); |
| 680 |
| 681 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_WH); |
| 682 h_factor = grp_scaling_factor(width, dst_width, 1); |
| 683 v_factor = grp_scaling_factor(height, dst_height, 0); |
| 684 |
| 685 temp_reg &= ~((0x3<<28)|(0x3<<12)); |
| 686 |
| 687 if (v_factor) { |
| 688 |
| 689 u32 reg = readl(mixer_base + S5P_MXR_CFG); |
| 690 |
| 691 /* In interlaced mode, vertical scaling must be |
| 692 * replaced by PROGRESSIVE_MODE - pixel duplication |
| 693 */ |
| 694 if (mode == TVOUT_1080I_50 || |
| 695 mode == TVOUT_1080I_59 || |
| 696 mode == TVOUT_1080I_60) { |
| 697 /* scaled up by progressive setting */ |
| 698 reg |= S5P_MXR_PROGRESSVE_MODE; |
| 699 writel(reg, mixer_base + S5P_MXR_CFG); |
| 700 } else |
| 701 /* scaled up by scale factor */ |
| 702 temp_reg |= v_factor << 12; |
| 703 } else { |
| 704 u32 reg = readl(mixer_base + S5P_MXR_CFG); |
| 705 |
| 706 /* |
| 707 * if v_factor is 0, recover the original mode |
| 708 */ |
| 709 if (mode == TVOUT_1080I_50 || |
| 710 mode == TVOUT_1080I_59 || |
| 711 mode == TVOUT_1080I_60) { |
| 712 reg &= S5P_MXR_INTERLACE_MODE; |
| 713 writel(reg, mixer_base + S5P_MXR_CFG); |
| 714 } |
| 715 } |
| 716 temp_reg |= h_factor << 28; |
| 717 writel(temp_reg , mixer_base + S5P_MXR_GRAPHIC0_WH); |
| 718 break; |
| 719 |
| 720 case VM_GPR1_LAYER: |
| 721 temp_reg = (blank_change) ? |
| 722 S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL : |
| 723 S5P_MXR_BLANK_CHANGE_NEW_PIXEL; |
| 724 temp_reg |= (premul) ? |
| 725 S5P_MXR_PRE_MUL_MODE : S5P_MXR_NORMAL_MODE; |
| 726 temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE : |
| 727 S5P_MXR_WIN_BLEND_DISABLE; |
| 728 temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE : |
| 729 S5P_MXR_PIXEL_BLEND_DISABLE; |
| 730 temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color); |
| 731 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha); |
| 732 |
| 733 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG); |
| 734 writel(S5P_MXR_GPR_BLANK_COLOR(blank_color), |
| 735 mixer_base + S5P_MXR_GRAPHIC1_BLANK); |
| 736 |
| 737 VMPRINTK("--(0x%x)\n\r", |
| 738 readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)); |
| 739 VMPRINTK("--(0x%x)\n\r", |
| 740 readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); |
| 741 |
| 742 tv_vm_set_grp_layer_size(layer, span, width, height, |
| 743 src_offs_x, src_offs_y); |
| 744 |
| 745 tv_vm_set_grp_base_address(layer, base_addr); |
| 746 tv_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y); |
| 747 |
| 748 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_WH); |
| 749 h_factor = grp_scaling_factor(width, dst_width, 1); |
| 750 v_factor = grp_scaling_factor(height, dst_height, 0); |
| 751 |
| 752 temp_reg &= ~((0x3<<28)|(0x3<<12)); |
| 753 |
| 754 if (v_factor) { |
| 755 |
| 756 u32 reg = readl(mixer_base + S5P_MXR_CFG); |
| 757 |
| 758 /* In interlaced mode, vertical scaling must be |
| 759 * replaced by PROGRESSIVE_MODE - pixel duplication |
| 760 */ |
| 761 if (mode == TVOUT_1080I_50 || |
| 762 mode == TVOUT_1080I_59 || |
| 763 mode == TVOUT_1080I_60) { |
| 764 /* scaled up by progressive setting */ |
| 765 reg |= S5P_MXR_PROGRESSVE_MODE; |
| 766 writel(reg, mixer_base + S5P_MXR_CFG); |
| 767 } else |
| 768 /* scaled up by scale factor */ |
| 769 temp_reg |= v_factor << 12; |
| 770 } else { |
| 771 u32 reg = readl(mixer_base + S5P_MXR_CFG); |
| 772 |
| 773 /* |
| 774 * if v_factor is 0, recover the original mode |
| 775 */ |
| 776 if (mode == TVOUT_1080I_50 || |
| 777 mode == TVOUT_1080I_59 || |
| 778 mode == TVOUT_1080I_60) { |
| 779 reg &= S5P_MXR_INTERLACE_MODE; |
| 780 writel(reg, mixer_base + S5P_MXR_CFG); |
| 781 } |
| 782 } |
| 783 |
| 784 temp_reg |= h_factor << 28; |
| 785 |
| 786 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_WH); |
| 787 break; |
| 788 |
| 789 default: |
| 790 VMPRINTK("invalid layer parameter = %d\n\r", layer); |
| 791 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 792 } |
| 793 |
| 794 tv_vm_set_layer_priority(layer, priority); |
| 795 |
| 796 tv_vm_set_layer_show(layer, show); |
| 797 |
| 798 return VMIXER_NO_ERROR; |
| 799 } |
| 800 |
| 801 void tv_vm_init_bg_dither_enable(bool cr_dither_enable, |
| 802 bool cb_dither_enable, |
| 803 bool y_dither_enable) |
| 804 { |
| 805 u32 temp_reg = 0; |
| 806 |
| 807 VMPRINTK("%d,%d,%d\n\r", |
| 808 cr_dither_enable, cb_dither_enable, y_dither_enable); |
| 809 |
| 810 temp_reg = (cr_dither_enable) ? |
| 811 (temp_reg | S5P_MXR_BG_CR_DIHER_EN) : |
| 812 (temp_reg & ~S5P_MXR_BG_CR_DIHER_EN); |
| 813 temp_reg = (cb_dither_enable) ? |
| 814 (temp_reg | S5P_MXR_BG_CB_DIHER_EN) : |
| 815 (temp_reg & ~S5P_MXR_BG_CB_DIHER_EN); |
| 816 temp_reg = (y_dither_enable) ? |
| 817 (temp_reg | S5P_MXR_BG_Y_DIHER_EN) : |
| 818 (temp_reg & ~S5P_MXR_BG_Y_DIHER_EN); |
| 819 |
| 820 writel(temp_reg, mixer_base + S5P_MXR_BG_CFG); |
| 821 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_BG_CFG)); |
| 822 |
| 823 } |
| 824 |
| 825 |
| 826 enum s5p_tv_vmx_err tv_vm_init_bg_color(enum s5p_tv_vmx_bg_color_num color_num, |
| 827 u32 color_y, |
| 828 u32 color_cb, |
| 829 u32 color_cr) |
| 830 { |
| 831 return tv_vm_set_bg_color(color_num, color_y, color_cb, color_cr); |
| 832 } |
| 833 |
| 834 enum s5p_tv_vmx_err tv_vm_init_csc_coef(enum s5p_yuv_fmt_component component, |
| 835 enum s5p_tv_coef_y_mode mode, |
| 836 u32 coeff0, |
| 837 u32 coeff1, |
| 838 u32 coeff2) |
| 839 { |
| 840 u32 mxr_cm; |
| 841 |
| 842 VMPRINTK("%d,%d,%d,%d,%d\n\r", component, mode, coeff0, coeff1, coeff2); |
| 843 |
| 844 switch (component) { |
| 845 |
| 846 case TVOUT_YUV_Y: |
| 847 mxr_cm = (mode == VMIXER_COEF_Y_WIDE) ? |
| 848 S5P_MXR_BG_COLOR_WIDE : S5P_MXR_BG_COLOR_NARROW; |
| 849 mxr_cm |= S5P_MXR_BG_COEFF_0(coeff0) | |
| 850 S5P_MXR_BG_COEFF_1(coeff1) | |
| 851 S5P_MXR_BG_COEFF_2(coeff2); |
| 852 writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_Y); |
| 853 VMPRINTK("--(0x%x)\n\r", |
| 854 readl(mixer_base + S5P_MXR_CM_COEFF_Y)); |
| 855 break; |
| 856 |
| 857 case TVOUT_YUV_CB: |
| 858 mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) | |
| 859 S5P_MXR_BG_COEFF_1(coeff1) | |
| 860 S5P_MXR_BG_COEFF_2(coeff2); |
| 861 writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_CB); |
| 862 VMPRINTK("--(0x%x)\n\r", |
| 863 readl(mixer_base + S5P_MXR_CM_COEFF_CB)); |
| 864 break; |
| 865 |
| 866 case TVOUT_YUV_CR: |
| 867 mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) | |
| 868 S5P_MXR_BG_COEFF_1(coeff1) | |
| 869 S5P_MXR_BG_COEFF_2(coeff2); |
| 870 writel(mxr_cm, S5P_MXR_CM_COEFF_CR); |
| 871 VMPRINTK("--(0x%x)\n\r", |
| 872 readl(mixer_base + S5P_MXR_CM_COEFF_CR)); |
| 873 break; |
| 874 |
| 875 default: |
| 876 VMPRINTK("invalid component parameter = %d\n\r", component); |
| 877 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 878 } |
| 879 |
| 880 return VMIXER_NO_ERROR; |
| 881 } |
| 882 |
| 883 void tv_vm_init_csc_coef_default(enum s5p_tv_vmx_csc_type csc_type) |
| 884 { |
| 885 VMPRINTK("%d\n\r", csc_type); |
| 886 |
| 887 switch (csc_type) { |
| 888 |
| 889 case VMIXER_CSC_RGB_TO_YUV601_LR: |
| 890 writel((0 << 30) | (153 << 20) | (300 << 10) | (58 << 0), |
| 891 mixer_base + S5P_MXR_CM_COEFF_Y); |
| 892 writel((936 << 20) | (851 << 10) | (262 << 0), |
| 893 mixer_base + S5P_MXR_CM_COEFF_CB); |
| 894 writel((262 << 20) | (805 << 10) | (982 << 0), |
| 895 mixer_base + S5P_MXR_CM_COEFF_CR); |
| 896 break; |
| 897 |
| 898 case VMIXER_CSC_RGB_TO_YUV601_FR: |
| 899 writel((1 << 30) | (132 << 20) | (258 << 10) | (50 << 0), |
| 900 mixer_base + S5P_MXR_CM_COEFF_Y); |
| 901 writel((948 << 20) | (875 << 10) | (225 << 0), |
| 902 mixer_base + S5P_MXR_CM_COEFF_CB); |
| 903 writel((225 << 20) | (836 << 10) | (988 << 0), |
| 904 mixer_base + S5P_MXR_CM_COEFF_CR); |
| 905 break; |
| 906 |
| 907 case VMIXER_CSC_RGB_TO_YUV709_LR: |
| 908 writel((0 << 30) | (109 << 20) | (366 << 10) | (36 << 0), |
| 909 mixer_base + S5P_MXR_CM_COEFF_Y); |
| 910 writel((964 << 20) | (822 << 10) | (216 << 0), |
| 911 mixer_base + S5P_MXR_CM_COEFF_CB); |
| 912 writel((262 << 20) | (787 << 10) | (1000 << 0), |
| 913 mixer_base + S5P_MXR_CM_COEFF_CR); |
| 914 break; |
| 915 |
| 916 case VMIXER_CSC_RGB_TO_YUV709_FR: |
| 917 writel((1 << 30) | (94 << 20) | (314 << 10) | (32 << 0), |
| 918 mixer_base + S5P_MXR_CM_COEFF_Y); |
| 919 writel((972 << 20) | (851 << 10) | (225 << 0), |
| 920 mixer_base + S5P_MXR_CM_COEFF_CB); |
| 921 writel((225 << 20) | (820 << 10) | (1004 << 0), |
| 922 mixer_base + S5P_MXR_CM_COEFF_CR); |
| 923 break; |
| 924 |
| 925 default: |
| 926 VMPRINTK(" invalid csc_type parameter = %d\n\r", csc_type); |
| 927 break; |
| 928 } |
| 929 |
| 930 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_Y)); |
| 931 |
| 932 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CB)); |
| 933 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CR)); |
| 934 } |
| 935 |
| 936 enum s5p_tv_vmx_err tv_vm_get_layer_info(enum s5p_tv_vmx_layer layer, |
| 937 bool *show, |
| 938 u32 *priority) |
| 939 { |
| 940 VMPRINTK("%d\n\r", layer); |
| 941 |
| 942 switch (layer) { |
| 943 |
| 944 case VM_VIDEO_LAYER: |
| 945 *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & |
| 946 S5P_MXR_VIDEO_LAYER_SHOW) ? 1 : 0; |
| 947 *priority = S5P_MXR_VP_LAYER_PRIORITY_INFO( |
| 948 readl(mixer_base + S5P_MXR_LAYER_CFG)); |
| 949 break; |
| 950 |
| 951 case VM_GPR0_LAYER: |
| 952 *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & |
| 953 S5P_MXR_GRAPHIC0_LAYER_SHOW) ? 1 : 0; |
| 954 *priority = S5P_MXR_GRP0_LAYER_PRIORITY_INFO( |
| 955 readl(mixer_base + S5P_MXR_LAYER_CFG)); |
| 956 break; |
| 957 |
| 958 case VM_GPR1_LAYER: |
| 959 *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) & |
| 960 S5P_MXR_GRAPHIC1_LAYER_SHOW) ? 1 : 0; |
| 961 *priority = S5P_MXR_GRP1_LAYER_PRIORITY_INFO( |
| 962 readl(mixer_base + S5P_MXR_LAYER_CFG)); |
| 963 break; |
| 964 |
| 965 default: |
| 966 VMPRINTK("invalid layer parameter = %d\n\r", layer); |
| 967 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 968 } |
| 969 |
| 970 VMPRINTK("%d,%d\n\r", *show, *priority); |
| 971 |
| 972 return VMIXER_NO_ERROR; |
| 973 } |
| 974 |
| 975 /* |
| 976 * start - start functions are only called under stopping vmixer |
| 977 */ |
| 978 |
| 979 void tv_vm_start(void) |
| 980 { |
| 981 VMPRINTK("()\n\r"); |
| 982 writel((readl(mixer_base + S5P_MXR_STATUS) | S5P_MXR_MIXER_START), |
| 983 mixer_base + S5P_MXR_STATUS); |
| 984 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_STATUS)); |
| 985 |
| 986 |
| 987 VMPRINTK("S5P_MXR_STATUS \t\t 0x%08x\n ", |
| 988 readl(mixer_base + S5P_MXR_STATUS)); |
| 989 VMPRINTK("S5P_MXR_INT_EN \t\t 0x%08x\n ", |
| 990 readl(mixer_base + S5P_MXR_INT_EN)); |
| 991 VMPRINTK("S5P_MXR_BG_CFG \t\t 0x%08x\n ", |
| 992 readl(mixer_base + S5P_MXR_BG_CFG)); |
| 993 VMPRINTK("S5P_MXR_BG_COLOR0 \t\t 0x%08x\n ", |
| 994 readl(mixer_base + S5P_MXR_BG_COLOR0)); |
| 995 VMPRINTK("S5P_MXR_BG_COLOR1 \t\t 0x%08x\n ", |
| 996 readl(mixer_base + S5P_MXR_BG_COLOR1)); |
| 997 VMPRINTK("S5P_MXR_BG_COLOR2 \t\t 0x%08x\n ", |
| 998 readl(mixer_base + S5P_MXR_BG_COLOR2)); |
| 999 VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ", |
| 1000 readl(mixer_base + S5P_MXR_CM_COEFF_Y)); |
| 1001 VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ", |
| 1002 readl(mixer_base + S5P_MXR_CM_COEFF_CB)); |
| 1003 VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ", |
| 1004 readl(mixer_base + S5P_MXR_CM_COEFF_CR)); |
| 1005 VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ", |
| 1006 readl(mixer_base + S5P_MXR_CM_COEFF_Y)); |
| 1007 VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ", |
| 1008 readl(mixer_base + S5P_MXR_CM_COEFF_CB)); |
| 1009 VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ", |
| 1010 readl(mixer_base + S5P_MXR_CM_COEFF_CR)); |
| 1011 VMPRINTK("S5P_MXR_GRAPHIC0_CFG \t\t 0x%08x\n ", |
| 1012 readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)); |
| 1013 VMPRINTK("S5P_MXR_GRAPHIC0_BASE \t\t 0x%08x\n ", |
| 1014 readl(mixer_base + S5P_MXR_GRAPHIC0_BASE)); |
| 1015 VMPRINTK("S5P_MXR_GRAPHIC0_SPAN \t\t 0x%08x\n ", |
| 1016 readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN)); |
| 1017 VMPRINTK("S5P_MXR_GRAPHIC0_WH \t\t 0x%08x\n ", |
| 1018 readl(mixer_base + S5P_MXR_GRAPHIC0_WH)); |
| 1019 VMPRINTK("S5P_MXR_GRAPHIC0_SXY \t\t 0x%08x\n ", |
| 1020 readl(mixer_base + S5P_MXR_GRAPHIC0_SXY)); |
| 1021 VMPRINTK("S5P_MXR_GRAPHIC0_DXY \t\t 0x%08x\n ", |
| 1022 readl(mixer_base + S5P_MXR_GRAPHIC0_DXY)); |
| 1023 VMPRINTK("S5P_MXR_GRAPHIC0_BLANK \t\t 0x%08x\n ", |
| 1024 readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK)); |
| 1025 VMPRINTK("S5P_MXR_GRAPHIC1_BASE \t\t 0x%08x\n ", |
| 1026 readl(mixer_base + S5P_MXR_GRAPHIC1_BASE)); |
| 1027 VMPRINTK("S5P_MXR_GRAPHIC1_SPAN \t\t 0x%08x\n ", |
| 1028 readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN)); |
| 1029 VMPRINTK("S5P_MXR_GRAPHIC1_WH \t\t 0x%08x\n ", |
| 1030 readl(mixer_base + S5P_MXR_GRAPHIC1_WH)); |
| 1031 VMPRINTK("S5P_MXR_GRAPHIC1_SXY \t\t 0x%08x\n ", |
| 1032 readl(mixer_base + S5P_MXR_GRAPHIC1_SXY)); |
| 1033 VMPRINTK("S5P_MXR_GRAPHIC1_DXY \t\t 0x%08x\n ", |
| 1034 readl(mixer_base + S5P_MXR_GRAPHIC1_DXY)); |
| 1035 VMPRINTK("S5P_MXR_GRAPHIC1_BLANK \t\t 0x%08x\n ", |
| 1036 readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK)); |
| 1037 VMPRINTK("S5P_MXR_CFG \t\t 0x%08x\n ", readl(mixer_base + S5P_MXR_CFG)); |
| 1038 VMPRINTK("S5P_MXR_LAYER_CFG \t\t 0x%08x\n ", |
| 1039 readl(mixer_base + S5P_MXR_LAYER_CFG)); |
| 1040 |
| 1041 } |
| 1042 |
| 1043 /* |
| 1044 * stop - stop functions are only called under running vmixer |
| 1045 */ |
| 1046 void tv_vm_stop(void) |
| 1047 { |
| 1048 u32 reg = readl(mixer_base + S5P_MXR_STATUS); |
| 1049 |
| 1050 reg &= ~S5P_MXR_MIXER_START; |
| 1051 |
| 1052 writel(reg, mixer_base + S5P_MXR_STATUS); |
| 1053 |
| 1054 do { |
| 1055 reg = readl(mixer_base + S5P_MXR_STATUS); |
| 1056 } while (reg & S5P_MXR_MIXER_START); |
| 1057 } |
| 1058 |
| 1059 /* |
| 1060 * interrupt - for debug |
| 1061 */ |
| 1062 enum s5p_tv_vmx_err tv_vm_set_underflow_interrupt_enable( |
| 1063 enum s5p_tv_vmx_layer layer, bool en) |
| 1064 { |
| 1065 u32 enablemaks; |
| 1066 |
| 1067 VMPRINTK("%d,%d\n\r", layer, en); |
| 1068 |
| 1069 switch (layer) { |
| 1070 |
| 1071 case VM_VIDEO_LAYER: |
| 1072 enablemaks = S5P_MXR_VP_INT_ENABLE; |
| 1073 break; |
| 1074 |
| 1075 case VM_GPR0_LAYER: |
| 1076 enablemaks = S5P_MXR_GRP0_INT_ENABLE; |
| 1077 break; |
| 1078 |
| 1079 case VM_GPR1_LAYER: |
| 1080 enablemaks = S5P_MXR_GRP1_INT_ENABLE; |
| 1081 break; |
| 1082 |
| 1083 default: |
| 1084 VMPRINTK("invalid layer parameter = %d\n\r", layer); |
| 1085 return S5P_TV_VMX_ERR_INVALID_PARAM; |
| 1086 } |
| 1087 |
| 1088 if (en) { |
| 1089 writel((readl(mixer_base + S5P_MXR_INT_EN) | enablemaks), |
| 1090 mixer_base + S5P_MXR_INT_EN); |
| 1091 } else { |
| 1092 writel((readl(mixer_base + S5P_MXR_INT_EN) & ~enablemaks), |
| 1093 mixer_base + S5P_MXR_INT_EN); |
| 1094 } |
| 1095 |
| 1096 VMPRINTK("0x%x)\n\r", readl(mixer_base + S5P_MXR_INT_EN)); |
| 1097 |
| 1098 return VMIXER_NO_ERROR; |
| 1099 } |
| 1100 |
| 1101 |
| 1102 enum s5p_tv_vmx_err tv_vm_set_vsync_interrupt(bool en) |
| 1103 { |
| 1104 if (en) { |
| 1105 writel(S5P_MXR_VSYNC_INT_CLEARED, mixer_base + |
| 1106 S5P_MXR_INT_STATUS); |
| 1107 writel((readl(mixer_base + S5P_MXR_INT_EN) | |
| 1108 S5P_MXR_VSYNC_INT_ENABLE), |
| 1109 mixer_base + S5P_MXR_INT_EN); |
| 1110 } else { |
| 1111 writel((readl(mixer_base + S5P_MXR_INT_EN) & |
| 1112 ~S5P_MXR_VSYNC_INT_ENABLE), |
| 1113 mixer_base + S5P_MXR_INT_EN); |
| 1114 } |
| 1115 |
| 1116 VMPRINTK("0x%x)\n\r", readl(mixer_base + S5P_MXR_INT_EN)); |
| 1117 |
| 1118 return VMIXER_NO_ERROR; |
| 1119 } |
| 1120 |
| 1121 void tv_vm_clear_pend_all(void) |
| 1122 { |
| 1123 writel(S5P_MXR_INT_FIRED | S5P_MXR_VP_INT_FIRED | |
| 1124 S5P_MXR_GRP0_INT_FIRED | S5P_MXR_GRP1_INT_FIRED, |
| 1125 mixer_base + S5P_MXR_INT_EN); |
| 1126 } |
| 1127 |
| 1128 irqreturn_t tv_mixer_irq(int irq, void *dev_id) |
| 1129 { |
| 1130 bool v_i_f; |
| 1131 bool g0_i_f; |
| 1132 bool g1_i_f; |
| 1133 bool mxr_i_f; |
| 1134 u32 temp_reg = 0; |
| 1135 |
| 1136 v_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) |
| 1137 & S5P_MXR_VP_INT_FIRED) ? true : false; |
| 1138 g0_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) |
| 1139 & S5P_MXR_GRP0_INT_FIRED) ? true : false; |
| 1140 g1_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) |
| 1141 & S5P_MXR_GRP1_INT_FIRED) ? true : false; |
| 1142 mxr_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS) |
| 1143 & S5P_MXR_INT_FIRED) ? true : false; |
| 1144 |
| 1145 if (mxr_i_f) { |
| 1146 temp_reg |= S5P_MXR_INT_FIRED; |
| 1147 |
| 1148 if (v_i_f) { |
| 1149 temp_reg |= S5P_MXR_VP_INT_FIRED; |
| 1150 printk(KERN_ERR "VP fifo under run!!\n\r"); |
| 1151 } |
| 1152 |
| 1153 if (g0_i_f) { |
| 1154 temp_reg |= S5P_MXR_GRP0_INT_FIRED; |
| 1155 printk(KERN_ERR "GRP0 fifo under run!!\n\r"); |
| 1156 } |
| 1157 |
| 1158 if (g1_i_f) { |
| 1159 temp_reg |= S5P_MXR_GRP1_INT_FIRED; |
| 1160 printk(KERN_ERR "GRP1 fifo under run!!\n\r"); |
| 1161 } |
| 1162 |
| 1163 if (!v_i_f && !g0_i_f && !g1_i_f) { |
| 1164 writel(S5P_MXR_VSYNC_INT_CLEARED, |
| 1165 mixer_base + S5P_MXR_INT_STATUS); |
| 1166 wake_up(&s5ptv_wq); |
| 1167 } else |
| 1168 writel(temp_reg, mixer_base + S5P_MXR_INT_STATUS); |
| 1169 |
| 1170 } |
| 1171 return IRQ_HANDLED; |
| 1172 } |
| 1173 |
| 1174 int __init tv_mixer_probe(struct platform_device *pdev, u32 res_num) |
| 1175 { |
| 1176 struct resource *res; |
| 1177 size_t size; |
| 1178 |
| 1179 res = platform_get_resource(pdev, IORESOURCE_MEM, res_num); |
| 1180 |
| 1181 if (res == NULL) { |
| 1182 dev_err(&pdev->dev, |
| 1183 "failed to get memory region resource\n"); |
| 1184 goto error; |
| 1185 |
| 1186 } |
| 1187 |
| 1188 size = (res->end - res->start) + 1; |
| 1189 |
| 1190 mixer_mem = request_mem_region(res->start, size, pdev->name); |
| 1191 |
| 1192 if (mixer_mem == NULL) { |
| 1193 dev_err(&pdev->dev, |
| 1194 "failed to get memory region\n"); |
| 1195 goto error; |
| 1196 |
| 1197 } |
| 1198 |
| 1199 mixer_base = ioremap(res->start, size); |
| 1200 |
| 1201 if (mixer_base == NULL) { |
| 1202 dev_err(&pdev->dev, |
| 1203 "failed to ioremap address region\n"); |
| 1204 goto error; |
| 1205 |
| 1206 |
| 1207 } |
| 1208 |
| 1209 /* Initializing wait queue for mixer vsync interrupt */ |
| 1210 init_waitqueue_head(&s5ptv_wq); |
| 1211 return 0; |
| 1212 error: |
| 1213 return -ENOENT; |
| 1214 |
| 1215 } |
| 1216 |
| 1217 int __init tv_mixer_release(struct platform_device *pdev) |
| 1218 { |
| 1219 iounmap(mixer_base); |
| 1220 |
| 1221 /* remove memory region */ |
| 1222 if (mixer_mem != NULL) { |
| 1223 if (release_resource(mixer_mem)) |
| 1224 dev_err(&pdev->dev, |
| 1225 "Can't remove tvout drv !!\n"); |
| 1226 |
| 1227 kfree(mixer_mem); |
| 1228 |
| 1229 mixer_mem = NULL; |
| 1230 } |
| 1231 |
| 1232 return 0; |
| 1233 } |
OLD | NEW |