aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/davinci/dm644x_ccdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/davinci/dm644x_ccdc.c')
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c131
1 files changed, 127 insertions, 4 deletions
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
index b4cc96dc99ef..490aafb34e2f 100644
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -101,6 +101,9 @@ static u32 ccdc_raw_bayer_pix_formats[] =
101static u32 ccdc_raw_yuv_pix_formats[] = 101static u32 ccdc_raw_yuv_pix_formats[] =
102 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV}; 102 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
103 103
104/* CCDC Save/Restore context */
105static u32 ccdc_ctx[CCDC_REG_END / sizeof(u32)];
106
104/* register access routines */ 107/* register access routines */
105static inline u32 regr(u32 offset) 108static inline u32 regr(u32 offset)
106{ 109{
@@ -400,7 +403,11 @@ void ccdc_config_ycbcr(void)
400 * configure the FID, VD, HD pin polarity, 403 * configure the FID, VD, HD pin polarity,
401 * fld,hd pol positive, vd negative, 8-bit data 404 * fld,hd pol positive, vd negative, 8-bit data
402 */ 405 */
403 syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE | CCDC_SYN_MODE_8BITS; 406 syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE;
407 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
408 syn_mode |= CCDC_SYN_MODE_10BITS;
409 else
410 syn_mode |= CCDC_SYN_MODE_8BITS;
404 } else { 411 } else {
405 /* y/c external sync mode */ 412 /* y/c external sync mode */
406 syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) << 413 syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
@@ -419,8 +426,13 @@ void ccdc_config_ycbcr(void)
419 * configure the order of y cb cr in SDRAM, and disable latch 426 * configure the order of y cb cr in SDRAM, and disable latch
420 * internal register on vsync 427 * internal register on vsync
421 */ 428 */
422 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) | 429 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
423 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG); 430 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
431 CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_BW656_10BIT,
432 CCDC_CCDCFG);
433 else
434 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
435 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
424 436
425 /* 437 /*
426 * configure the horizontal line offset. This should be a 438 * configure the horizontal line offset. This should be a
@@ -435,7 +447,6 @@ void ccdc_config_ycbcr(void)
435 447
436 ccdc_sbl_reset(); 448 ccdc_sbl_reset();
437 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n"); 449 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
438 ccdc_readregs();
439} 450}
440 451
441static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp) 452static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
@@ -827,6 +838,7 @@ static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
827 case VPFE_BT656: 838 case VPFE_BT656:
828 case VPFE_YCBCR_SYNC_16: 839 case VPFE_YCBCR_SYNC_16:
829 case VPFE_YCBCR_SYNC_8: 840 case VPFE_YCBCR_SYNC_8:
841 case VPFE_BT656_10BIT:
830 ccdc_cfg.ycbcr.vd_pol = params->vdpol; 842 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
831 ccdc_cfg.ycbcr.hd_pol = params->hdpol; 843 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
832 break; 844 break;
@@ -837,6 +849,87 @@ static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
837 return 0; 849 return 0;
838} 850}
839 851
852static void ccdc_save_context(void)
853{
854 ccdc_ctx[CCDC_PCR >> 2] = regr(CCDC_PCR);
855 ccdc_ctx[CCDC_SYN_MODE >> 2] = regr(CCDC_SYN_MODE);
856 ccdc_ctx[CCDC_HD_VD_WID >> 2] = regr(CCDC_HD_VD_WID);
857 ccdc_ctx[CCDC_PIX_LINES >> 2] = regr(CCDC_PIX_LINES);
858 ccdc_ctx[CCDC_HORZ_INFO >> 2] = regr(CCDC_HORZ_INFO);
859 ccdc_ctx[CCDC_VERT_START >> 2] = regr(CCDC_VERT_START);
860 ccdc_ctx[CCDC_VERT_LINES >> 2] = regr(CCDC_VERT_LINES);
861 ccdc_ctx[CCDC_CULLING >> 2] = regr(CCDC_CULLING);
862 ccdc_ctx[CCDC_HSIZE_OFF >> 2] = regr(CCDC_HSIZE_OFF);
863 ccdc_ctx[CCDC_SDOFST >> 2] = regr(CCDC_SDOFST);
864 ccdc_ctx[CCDC_SDR_ADDR >> 2] = regr(CCDC_SDR_ADDR);
865 ccdc_ctx[CCDC_CLAMP >> 2] = regr(CCDC_CLAMP);
866 ccdc_ctx[CCDC_DCSUB >> 2] = regr(CCDC_DCSUB);
867 ccdc_ctx[CCDC_COLPTN >> 2] = regr(CCDC_COLPTN);
868 ccdc_ctx[CCDC_BLKCMP >> 2] = regr(CCDC_BLKCMP);
869 ccdc_ctx[CCDC_FPC >> 2] = regr(CCDC_FPC);
870 ccdc_ctx[CCDC_FPC_ADDR >> 2] = regr(CCDC_FPC_ADDR);
871 ccdc_ctx[CCDC_VDINT >> 2] = regr(CCDC_VDINT);
872 ccdc_ctx[CCDC_ALAW >> 2] = regr(CCDC_ALAW);
873 ccdc_ctx[CCDC_REC656IF >> 2] = regr(CCDC_REC656IF);
874 ccdc_ctx[CCDC_CCDCFG >> 2] = regr(CCDC_CCDCFG);
875 ccdc_ctx[CCDC_FMTCFG >> 2] = regr(CCDC_FMTCFG);
876 ccdc_ctx[CCDC_FMT_HORZ >> 2] = regr(CCDC_FMT_HORZ);
877 ccdc_ctx[CCDC_FMT_VERT >> 2] = regr(CCDC_FMT_VERT);
878 ccdc_ctx[CCDC_FMT_ADDR0 >> 2] = regr(CCDC_FMT_ADDR0);
879 ccdc_ctx[CCDC_FMT_ADDR1 >> 2] = regr(CCDC_FMT_ADDR1);
880 ccdc_ctx[CCDC_FMT_ADDR2 >> 2] = regr(CCDC_FMT_ADDR2);
881 ccdc_ctx[CCDC_FMT_ADDR3 >> 2] = regr(CCDC_FMT_ADDR3);
882 ccdc_ctx[CCDC_FMT_ADDR4 >> 2] = regr(CCDC_FMT_ADDR4);
883 ccdc_ctx[CCDC_FMT_ADDR5 >> 2] = regr(CCDC_FMT_ADDR5);
884 ccdc_ctx[CCDC_FMT_ADDR6 >> 2] = regr(CCDC_FMT_ADDR6);
885 ccdc_ctx[CCDC_FMT_ADDR7 >> 2] = regr(CCDC_FMT_ADDR7);
886 ccdc_ctx[CCDC_PRGEVEN_0 >> 2] = regr(CCDC_PRGEVEN_0);
887 ccdc_ctx[CCDC_PRGEVEN_1 >> 2] = regr(CCDC_PRGEVEN_1);
888 ccdc_ctx[CCDC_PRGODD_0 >> 2] = regr(CCDC_PRGODD_0);
889 ccdc_ctx[CCDC_PRGODD_1 >> 2] = regr(CCDC_PRGODD_1);
890 ccdc_ctx[CCDC_VP_OUT >> 2] = regr(CCDC_VP_OUT);
891}
892
893static void ccdc_restore_context(void)
894{
895 regw(ccdc_ctx[CCDC_SYN_MODE >> 2], CCDC_SYN_MODE);
896 regw(ccdc_ctx[CCDC_HD_VD_WID >> 2], CCDC_HD_VD_WID);
897 regw(ccdc_ctx[CCDC_PIX_LINES >> 2], CCDC_PIX_LINES);
898 regw(ccdc_ctx[CCDC_HORZ_INFO >> 2], CCDC_HORZ_INFO);
899 regw(ccdc_ctx[CCDC_VERT_START >> 2], CCDC_VERT_START);
900 regw(ccdc_ctx[CCDC_VERT_LINES >> 2], CCDC_VERT_LINES);
901 regw(ccdc_ctx[CCDC_CULLING >> 2], CCDC_CULLING);
902 regw(ccdc_ctx[CCDC_HSIZE_OFF >> 2], CCDC_HSIZE_OFF);
903 regw(ccdc_ctx[CCDC_SDOFST >> 2], CCDC_SDOFST);
904 regw(ccdc_ctx[CCDC_SDR_ADDR >> 2], CCDC_SDR_ADDR);
905 regw(ccdc_ctx[CCDC_CLAMP >> 2], CCDC_CLAMP);
906 regw(ccdc_ctx[CCDC_DCSUB >> 2], CCDC_DCSUB);
907 regw(ccdc_ctx[CCDC_COLPTN >> 2], CCDC_COLPTN);
908 regw(ccdc_ctx[CCDC_BLKCMP >> 2], CCDC_BLKCMP);
909 regw(ccdc_ctx[CCDC_FPC >> 2], CCDC_FPC);
910 regw(ccdc_ctx[CCDC_FPC_ADDR >> 2], CCDC_FPC_ADDR);
911 regw(ccdc_ctx[CCDC_VDINT >> 2], CCDC_VDINT);
912 regw(ccdc_ctx[CCDC_ALAW >> 2], CCDC_ALAW);
913 regw(ccdc_ctx[CCDC_REC656IF >> 2], CCDC_REC656IF);
914 regw(ccdc_ctx[CCDC_CCDCFG >> 2], CCDC_CCDCFG);
915 regw(ccdc_ctx[CCDC_FMTCFG >> 2], CCDC_FMTCFG);
916 regw(ccdc_ctx[CCDC_FMT_HORZ >> 2], CCDC_FMT_HORZ);
917 regw(ccdc_ctx[CCDC_FMT_VERT >> 2], CCDC_FMT_VERT);
918 regw(ccdc_ctx[CCDC_FMT_ADDR0 >> 2], CCDC_FMT_ADDR0);
919 regw(ccdc_ctx[CCDC_FMT_ADDR1 >> 2], CCDC_FMT_ADDR1);
920 regw(ccdc_ctx[CCDC_FMT_ADDR2 >> 2], CCDC_FMT_ADDR2);
921 regw(ccdc_ctx[CCDC_FMT_ADDR3 >> 2], CCDC_FMT_ADDR3);
922 regw(ccdc_ctx[CCDC_FMT_ADDR4 >> 2], CCDC_FMT_ADDR4);
923 regw(ccdc_ctx[CCDC_FMT_ADDR5 >> 2], CCDC_FMT_ADDR5);
924 regw(ccdc_ctx[CCDC_FMT_ADDR6 >> 2], CCDC_FMT_ADDR6);
925 regw(ccdc_ctx[CCDC_FMT_ADDR7 >> 2], CCDC_FMT_ADDR7);
926 regw(ccdc_ctx[CCDC_PRGEVEN_0 >> 2], CCDC_PRGEVEN_0);
927 regw(ccdc_ctx[CCDC_PRGEVEN_1 >> 2], CCDC_PRGEVEN_1);
928 regw(ccdc_ctx[CCDC_PRGODD_0 >> 2], CCDC_PRGODD_0);
929 regw(ccdc_ctx[CCDC_PRGODD_1 >> 2], CCDC_PRGODD_1);
930 regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT);
931 regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR);
932}
840static struct ccdc_hw_device ccdc_hw_dev = { 933static struct ccdc_hw_device ccdc_hw_dev = {
841 .name = "DM6446 CCDC", 934 .name = "DM6446 CCDC",
842 .owner = THIS_MODULE, 935 .owner = THIS_MODULE,
@@ -945,10 +1038,40 @@ static int dm644x_ccdc_remove(struct platform_device *pdev)
945 return 0; 1038 return 0;
946} 1039}
947 1040
1041static int dm644x_ccdc_suspend(struct device *dev)
1042{
1043 /* Save CCDC context */
1044 ccdc_save_context();
1045 /* Disable CCDC */
1046 ccdc_enable(0);
1047 /* Disable both master and slave clock */
1048 clk_disable(ccdc_cfg.mclk);
1049 clk_disable(ccdc_cfg.sclk);
1050
1051 return 0;
1052}
1053
1054static int dm644x_ccdc_resume(struct device *dev)
1055{
1056 /* Enable both master and slave clock */
1057 clk_enable(ccdc_cfg.mclk);
1058 clk_enable(ccdc_cfg.sclk);
1059 /* Restore CCDC context */
1060 ccdc_restore_context();
1061
1062 return 0;
1063}
1064
1065static const struct dev_pm_ops dm644x_ccdc_pm_ops = {
1066 .suspend = dm644x_ccdc_suspend,
1067 .resume = dm644x_ccdc_resume,
1068};
1069
948static struct platform_driver dm644x_ccdc_driver = { 1070static struct platform_driver dm644x_ccdc_driver = {
949 .driver = { 1071 .driver = {
950 .name = "dm644x_ccdc", 1072 .name = "dm644x_ccdc",
951 .owner = THIS_MODULE, 1073 .owner = THIS_MODULE,
1074 .pm = &dm644x_ccdc_pm_ops,
952 }, 1075 },
953 .remove = __devexit_p(dm644x_ccdc_remove), 1076 .remove = __devexit_p(dm644x_ccdc_remove),
954 .probe = dm644x_ccdc_probe, 1077 .probe = dm644x_ccdc_probe,