diff options
Diffstat (limited to 'drivers/media/video/davinci/dm644x_ccdc.c')
| -rw-r--r-- | drivers/media/video/davinci/dm644x_ccdc.c | 131 |
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[] = | |||
| 101 | static u32 ccdc_raw_yuv_pix_formats[] = | 101 | static 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 */ | ||
| 105 | static u32 ccdc_ctx[CCDC_REG_END / sizeof(u32)]; | ||
| 106 | |||
| 104 | /* register access routines */ | 107 | /* register access routines */ |
| 105 | static inline u32 regr(u32 offset) | 108 | static 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 | ||
| 441 | static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp) | 452 | static 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 | ||
| 852 | static 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 | |||
| 893 | static 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 | } | ||
| 840 | static struct ccdc_hw_device ccdc_hw_dev = { | 933 | static 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 | ||
| 1041 | static 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 | |||
| 1054 | static 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 | |||
| 1065 | static const struct dev_pm_ops dm644x_ccdc_pm_ops = { | ||
| 1066 | .suspend = dm644x_ccdc_suspend, | ||
| 1067 | .resume = dm644x_ccdc_resume, | ||
| 1068 | }; | ||
| 1069 | |||
| 948 | static struct platform_driver dm644x_ccdc_driver = { | 1070 | static 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, |
