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

[media] davinci vpbe: add VENC block changes to enable dm365 and dm355

This patch implements necessary changes for enabling dm365 and
dm355 hardware for vpbe. The patch contains additional HD mode
support for dm365 (720p60, 1080i30) and appropriate register
modifications based on version numbers.

VPBE_VERSION_2 = dm365 specific
VPBE_VERSION_3 = dm355 specific

Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Manjunath Hadli and committed by
Mauro Carvalho Chehab
194ed219 4be54445

+185 -24
+181 -24
drivers/media/video/davinci/vpbe_venc.c
··· 99 99 return val; 100 100 } 101 101 102 + #define VDAC_COMPONENT 0x543 103 + #define VDAC_S_VIDEO 0x210 102 104 /* This function sets the dac of the VPBE for various outputs 103 105 */ 104 106 static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) ··· 111 109 venc_write(sd, VENC_DACSEL, 0); 112 110 break; 113 111 case 1: 114 - v4l2_dbg(debug, 1, sd, "Setting output to S-Video\n"); 115 - venc_write(sd, VENC_DACSEL, 0x210); 112 + v4l2_dbg(debug, 1, sd, "Setting output to Component\n"); 113 + venc_write(sd, VENC_DACSEL, VDAC_COMPONENT); 116 114 break; 117 - case 2: 118 - venc_write(sd, VENC_DACSEL, 0x543); 115 + case 2: 116 + v4l2_dbg(debug, 1, sd, "Setting output to S-video\n"); 117 + venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO); 119 118 break; 120 119 default: 121 120 return -EINVAL; ··· 127 124 128 125 static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) 129 126 { 127 + struct venc_state *venc = to_state(sd); 128 + struct venc_platform_data *pdata = venc->pdata; 130 129 v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n"); 131 130 132 131 if (benable) { ··· 160 155 161 156 /* Disable LCD output control (accepting default polarity) */ 162 157 venc_write(sd, VENC_LCDOUT, 0); 163 - venc_write(sd, VENC_CMPNT, 0x100); 158 + if (pdata->venc_type != VPBE_VERSION_3) 159 + venc_write(sd, VENC_CMPNT, 0x100); 164 160 venc_write(sd, VENC_HSPLS, 0); 165 161 venc_write(sd, VENC_HINT, 0); 166 162 venc_write(sd, VENC_HSTART, 0); ··· 184 178 } 185 179 } 186 180 181 + #define VDAC_CONFIG_SD_V3 0x0E21A6B6 182 + #define VDAC_CONFIG_SD_V2 0x081141CF 187 183 /* 188 184 * setting NTSC mode 189 185 */ 190 186 static int venc_set_ntsc(struct v4l2_subdev *sd) 191 187 { 188 + u32 val; 192 189 struct venc_state *venc = to_state(sd); 193 190 struct venc_platform_data *pdata = venc->pdata; 194 191 ··· 204 195 205 196 venc_enabledigitaloutput(sd, 0); 206 197 207 - /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ 208 - venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); 209 - /* Set REC656 Mode */ 210 - venc_write(sd, VENC_YCCCTL, 0x1); 211 - venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ); 212 - venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS); 198 + if (pdata->venc_type == VPBE_VERSION_3) { 199 + venc_write(sd, VENC_CLKCTL, 0x01); 200 + venc_write(sd, VENC_VIDCTL, 0); 201 + val = vdaccfg_write(sd, VDAC_CONFIG_SD_V3); 202 + } else if (pdata->venc_type == VPBE_VERSION_2) { 203 + venc_write(sd, VENC_CLKCTL, 0x01); 204 + venc_write(sd, VENC_VIDCTL, 0); 205 + vdaccfg_write(sd, VDAC_CONFIG_SD_V2); 206 + } else { 207 + /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ 208 + venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); 209 + /* Set REC656 Mode */ 210 + venc_write(sd, VENC_YCCCTL, 0x1); 211 + venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ); 212 + venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS); 213 + } 213 214 214 215 venc_write(sd, VENC_VMOD, 0); 215 216 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), ··· 239 220 static int venc_set_pal(struct v4l2_subdev *sd) 240 221 { 241 222 struct venc_state *venc = to_state(sd); 223 + struct venc_platform_data *pdata = venc->pdata; 242 224 243 225 v4l2_dbg(debug, 2, sd, "venc_set_pal\n"); 244 226 ··· 250 230 251 231 venc_enabledigitaloutput(sd, 0); 252 232 253 - /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ 254 - venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); 255 - /* Set REC656 Mode */ 256 - venc_write(sd, VENC_YCCCTL, 0x1); 233 + if (pdata->venc_type == VPBE_VERSION_3) { 234 + venc_write(sd, VENC_CLKCTL, 0x1); 235 + venc_write(sd, VENC_VIDCTL, 0); 236 + vdaccfg_write(sd, VDAC_CONFIG_SD_V3); 237 + } else if (pdata->venc_type == VPBE_VERSION_2) { 238 + venc_write(sd, VENC_CLKCTL, 0x1); 239 + venc_write(sd, VENC_VIDCTL, 0); 240 + vdaccfg_write(sd, VDAC_CONFIG_SD_V2); 241 + } else { 242 + /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ 243 + venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); 244 + /* Set REC656 Mode */ 245 + venc_write(sd, VENC_YCCCTL, 0x1); 246 + } 257 247 258 248 venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT, 259 249 VENC_SYNCCTL_OVD); ··· 282 252 return 0; 283 253 } 284 254 255 + #define VDAC_CONFIG_HD_V2 0x081141EF 285 256 /* 286 257 * venc_set_480p59_94 287 258 * ··· 294 263 struct venc_platform_data *pdata = venc->pdata; 295 264 296 265 v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n"); 266 + if ((pdata->venc_type != VPBE_VERSION_1) && 267 + (pdata->venc_type != VPBE_VERSION_2)) 268 + return -EINVAL; 297 269 298 270 /* Setup clock at VPSS & VENC for SD */ 299 271 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0) ··· 304 270 305 271 venc_enabledigitaloutput(sd, 0); 306 272 273 + if (pdata->venc_type == VPBE_VERSION_2) 274 + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); 307 275 venc_write(sd, VENC_OSDCLK0, 0); 308 276 venc_write(sd, VENC_OSDCLK1, 1); 309 - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, 310 - VENC_VDPRO_DAFRQ); 311 - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, 312 - VENC_VDPRO_DAUPS); 277 + 278 + if (pdata->venc_type == VPBE_VERSION_1) { 279 + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, 280 + VENC_VDPRO_DAFRQ); 281 + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, 282 + VENC_VDPRO_DAUPS); 283 + } 284 + 313 285 venc_write(sd, VENC_VMOD, 0); 314 286 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), 315 287 VENC_VMOD_VIE); ··· 342 302 343 303 v4l2_dbg(debug, 2, sd, "venc_set_576p50\n"); 344 304 305 + if ((pdata->venc_type != VPBE_VERSION_1) && 306 + (pdata->venc_type != VPBE_VERSION_2)) 307 + return -EINVAL; 345 308 /* Setup clock at VPSS & VENC for SD */ 346 309 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0) 347 310 return -EINVAL; 348 311 349 312 venc_enabledigitaloutput(sd, 0); 350 313 314 + if (pdata->venc_type == VPBE_VERSION_2) 315 + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); 316 + 351 317 venc_write(sd, VENC_OSDCLK0, 0); 352 318 venc_write(sd, VENC_OSDCLK1, 1); 353 319 354 - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, 355 - VENC_VDPRO_DAFRQ); 356 - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, 357 - VENC_VDPRO_DAUPS); 320 + if (pdata->venc_type == VPBE_VERSION_1) { 321 + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, 322 + VENC_VDPRO_DAFRQ); 323 + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, 324 + VENC_VDPRO_DAUPS); 325 + } 358 326 359 327 venc_write(sd, VENC_VMOD, 0); 360 328 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), ··· 375 327 VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD); 376 328 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); 377 329 330 + return 0; 331 + } 332 + 333 + /* 334 + * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only 335 + */ 336 + static int venc_set_720p60_internal(struct v4l2_subdev *sd) 337 + { 338 + struct venc_state *venc = to_state(sd); 339 + struct venc_platform_data *pdata = venc->pdata; 340 + 341 + if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0) 342 + return -EINVAL; 343 + 344 + venc_enabledigitaloutput(sd, 0); 345 + 346 + venc_write(sd, VENC_OSDCLK0, 0); 347 + venc_write(sd, VENC_OSDCLK1, 1); 348 + 349 + venc_write(sd, VENC_VMOD, 0); 350 + /* DM365 component HD mode */ 351 + venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), 352 + VENC_VMOD_VIE); 353 + venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); 354 + venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT), 355 + VENC_VMOD_TVTYP); 356 + venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); 357 + venc_write(sd, VENC_XHINTVL, 0); 358 + return 0; 359 + } 360 + 361 + /* 362 + * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only 363 + */ 364 + static int venc_set_1080i30_internal(struct v4l2_subdev *sd) 365 + { 366 + struct venc_state *venc = to_state(sd); 367 + struct venc_platform_data *pdata = venc->pdata; 368 + 369 + if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080P30) < 0) 370 + return -EINVAL; 371 + 372 + venc_enabledigitaloutput(sd, 0); 373 + 374 + venc_write(sd, VENC_OSDCLK0, 0); 375 + venc_write(sd, VENC_OSDCLK1, 1); 376 + 377 + 378 + venc_write(sd, VENC_VMOD, 0); 379 + /* DM365 component HD mode */ 380 + venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), 381 + VENC_VMOD_VIE); 382 + venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); 383 + venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT), 384 + VENC_VMOD_TVTYP); 385 + venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); 386 + venc_write(sd, VENC_XHINTVL, 0); 378 387 return 0; 379 388 } 380 389 ··· 450 345 static int venc_s_dv_preset(struct v4l2_subdev *sd, 451 346 struct v4l2_dv_preset *dv_preset) 452 347 { 348 + struct venc_state *venc = to_state(sd); 349 + int ret; 350 + 453 351 v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n"); 454 352 455 353 if (dv_preset->preset == V4L2_DV_576P50) 456 354 return venc_set_576p50(sd); 457 355 else if (dv_preset->preset == V4L2_DV_480P59_94) 458 356 return venc_set_480p59_94(sd); 459 - 357 + else if ((dv_preset->preset == V4L2_DV_720P60) && 358 + (venc->pdata->venc_type == VPBE_VERSION_2)) { 359 + /* TBD setup internal 720p mode here */ 360 + ret = venc_set_720p60_internal(sd); 361 + /* for DM365 VPBE, there is DAC inside */ 362 + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); 363 + return ret; 364 + } else if ((dv_preset->preset == V4L2_DV_1080I30) && 365 + (venc->pdata->venc_type == VPBE_VERSION_2)) { 366 + /* TBD setup internal 1080i mode here */ 367 + ret = venc_set_1080i30_internal(sd); 368 + /* for DM365 VPBE, there is DAC inside */ 369 + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); 370 + return ret; 371 + } 460 372 return -EINVAL; 461 373 } 462 374 ··· 630 508 goto release_venc_mem_region; 631 509 } 632 510 511 + if (venc->pdata->venc_type != VPBE_VERSION_1) { 512 + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 513 + if (!res) { 514 + dev_err(venc->pdev, 515 + "Unable to get VDAC_CONFIG address map\n"); 516 + ret = -ENODEV; 517 + goto unmap_venc_io; 518 + } 519 + 520 + if (!request_mem_region(res->start, 521 + resource_size(res), "venc")) { 522 + dev_err(venc->pdev, 523 + "Unable to reserve VDAC_CONFIG MMIO region\n"); 524 + ret = -ENODEV; 525 + goto unmap_venc_io; 526 + } 527 + 528 + venc->vdaccfg_reg = ioremap_nocache(res->start, 529 + resource_size(res)); 530 + if (!venc->vdaccfg_reg) { 531 + dev_err(venc->pdev, 532 + "Unable to map VDAC_CONFIG IO space\n"); 533 + ret = -ENODEV; 534 + goto release_vdaccfg_mem_region; 535 + } 536 + } 633 537 spin_lock_init(&venc->lock); 634 538 platform_set_drvdata(pdev, venc); 635 539 dev_notice(venc->pdev, "VENC sub device probe success\n"); 636 540 return 0; 637 541 542 + release_vdaccfg_mem_region: 543 + release_mem_region(res->start, resource_size(res)); 544 + unmap_venc_io: 545 + iounmap(venc->venc_base); 638 546 release_venc_mem_region: 639 547 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 640 548 release_mem_region(res->start, resource_size(res)); ··· 681 529 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 682 530 iounmap((void *)venc->venc_base); 683 531 release_mem_region(res->start, resource_size(res)); 532 + if (venc->pdata->venc_type != VPBE_VERSION_1) { 533 + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 534 + iounmap((void *)venc->vdaccfg_reg); 535 + release_mem_region(res->start, resource_size(res)); 536 + } 684 537 kfree(venc); 685 538 686 539 return 0;
+4
include/media/davinci/vpbe_venc.h
··· 29 29 30 30 struct venc_platform_data { 31 31 enum vpbe_version venc_type; 32 + int (*setup_pinmux)(enum v4l2_mbus_pixelcode if_type, 33 + int field); 32 34 int (*setup_clock)(enum vpbe_enc_timings_type type, 33 35 unsigned int mode); 36 + int (*setup_if_config)(enum v4l2_mbus_pixelcode pixcode); 34 37 /* Number of LCD outputs supported */ 35 38 int num_lcd_outputs; 39 + struct vpbe_if_params *lcd_if_params; 36 40 }; 37 41 38 42 enum venc_ioctls {