1397 static int __init enable_tve_setup(char *options) 一般情况,freescale会推荐在kernel命令行参数中使能TVE, 这个函数就是处理kernel传入的参数 'init=/init androidboot.console=ttymxc0 di1_primary video=mxcdi1fb:YUV444, 720x576-i@50 tve'
1198 static int tve_probe(struct platform_device *pdev) 1199 { 1200 int ret, i, primary = 0; 1201 struct resource *res; 1202 struct tve_platform_data *plat_data = pdev->dev.platform_data; 1203 u32 conf_reg; 1204 1205 if (g_enable_tve == false) 1206 return -EPERM; 1207 1208 INIT_LIST_HEAD(&tve_modelist.list); 1209 1210 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1211 if (res == NULL) 1212 return -ENOMEM; 1213 1214 tve.pdev = pdev; 1215 tve.base = ioremap(res->start, res->end - res->start); 1216 1217 tve.irq = platform_get_irq(pdev, 0); 1218 if (tve.irq < 0) { 1219 ret = tve.irq; 1220 goto err0; 1221 } 1222 1223 ret = request_irq(tve.irq, tve_detect_handler, 0, pdev->name, pdev); 1224 if (ret < 0) 1225 goto err0; 1226 1227 ret = device_create_file(&pdev->dev, &dev_attr_headphone); 1228 if (ret < 0) 1229 goto err1; 1230 1231 for (i = 0; i < num_registered_fb; i++) { 1232 if (strcmp(registered_fb[i]->fix.id, "DISP3 BG - DI1") == 0) { 1233 tve_fbi = registered_fb[i]; 1234 if (i == 0) { 1235 pr_info("TVE as primary display\n"); 1236 primary = 1; 1237 acquire_console_sem(); 1238 fb_blank(tve_fbi, FB_BLANK_POWERDOWN); 1239 release_console_sem(); 1240 } 1241 break; 1242 } 1243 } 1215 映射TVE寄存器地址到,结果保存到tve.base中 1217~1225 注册Cable Detect handler 1227 创建headphone属性文件,可以通过cat /sys/devices/platform/tve.0/headphone查看当前 cable 状态。 1231~1243 如果在kernel cmdline中指定了di1_primary,那么registered_fb[0] 的id就是"DISP3 BG - DI1",此时关闭fb_blank 1257 ~ 1266 获取di1和TVE的时钟 1267 ~ 1269 设置TVE的时钟rate,设置tve_clk1为di1_clk的父亲,这样启动di1就会为tve时钟上电; 1269 使能tve clk,这样才能操作tve的寄存器。 1271 ~ 1278 获取tve 版本;根据tve 的版本,来选择要操作的寄存器集合, 1292 ~ 1306 video_modes PAL, NTSC, 720P 是rev1和rev2都支持的video mode,rev2支持其他集中模式,XGA和SXGA仅在53上支持。 1309 初始化一个动作队列,这个工作队列是用来处理cable detect 1310 ~ 1313 设置cable detect register 1325 已经操作完TVE的寄存器,可以关闭clk了 1327 注册一个notifier callback,这样在fb event事件发生时就可以调用这个callback 1334 TVE是primary frame buffer,所以要显示logo 1343 不知道为什么要设置为 var.yres * 3 以后回来再看 1348~1356 关闭frame buffer再打开frame buffer
1179 static int _tve_get_revision(void)
1147 static ssize_t show_headphone(struct device *dev, 1157是真正的cable检测函数
632 static int tve_update_detect_status(void) 633 { 634 int old_detect = tve.detect; 635 u32 stat_lm, stat_sm, stat; 636 u32 int_ctl; 637 u32 cd_cont_reg; 638 u32 timeout = 40; 639 unsigned long lock_flags; 640 641 spin_lock_irqsave(&tve_lock, lock_flags); 642 643 if (!enabled) { 644 pr_warning("Warning: update tve status while it disabled!\n"); 645 tve.detect = 0; 646 goto done; 647 } 648 649 int_ctl = __raw_readl(tve.base + tve_regs->tve_int_cont_reg); 650 cd_cont_reg = __raw_readl(tve.base + tve_regs->tve_cd_cont_reg); 651 652 if ((cd_cont_reg & 0x1) == 0) { 653 pr_warning("Warning: pls enable TVE CD first!\n"); 654 goto done; 655 } 656 657 stat = __raw_readl(tve.base + tve_regs->tve_stat_reg); 658 while (((stat & CD_MON_END_INT) == 0) && (timeout > 0)) { 659 spin_unlock_irqrestore(&tve_lock, lock_flags); 660 msleep(2); 661 spin_lock_irqsave(&tve_lock, lock_flags); 662 timeout -= 2; 663 if (!enabled) { 664 pr_warning("Warning: update tve status while it disabled!\n"); 665 tve.detect = 0; 666 goto done; 667 } else 668 stat = __raw_readl(tve.base + tve_regs->tve_stat_reg); 669 } 670 if (((stat & CD_MON_END_INT) == 0) && (timeout <= 0)) { 671 pr_warning("Warning: get detect result without CD_MON_END_INT!\n"); 672 goto done; 673 } 674 675 stat = stat >> tve_reg_fields->cd_ch_stat_offset; 676 stat_lm = stat & (CD_CH_0_LM_ST | CD_CH_1_LM_ST | CD_CH_2_LM_ST); 677 if ((stat_lm == (CD_CH_0_LM_ST | CD_CH_1_LM_ST | CD_CH_2_LM_ST)) && 678 ((stat & (CD_CH_0_SM_ST | CD_CH_1_SM_ST | CD_CH_2_SM_ST)) == 0) 679 ) { 680 tve.detect = 3; 681 tve.output_mode = YPBPR; 682 } else if ((stat_lm == (CD_CH_0_LM_ST | CD_CH_1_LM_ST)) && 683 ((stat & (CD_CH_0_SM_ST | CD_CH_1_SM_ST)) == 0)) { 684 tve.detect = 4; 685 tve.output_mode = SVIDEO; 686 } else if (stat_lm == CD_CH_0_LM_ST) { 687 stat_sm = stat & CD_CH_0_SM_ST; 688 if (stat_sm != 0) { 689 /* headset */ 690 tve.detect = 2; 691 tve.output_mode = TV_OFF; 692 } else { 693 tve.detect = 1; 694 tve.output_mode = CVBS0; 695 } 696 } else if (stat_lm == CD_CH_2_LM_ST) { 697 stat_sm = stat & CD_CH_2_SM_ST; 698 if (stat_sm != 0) { 699 /* headset */ 700 tve.detect = 2; 701 tve.output_mode = TV_OFF; 702 } else { 703 tve.detect = 1; 704 tve.output_mode = CVBS2; 705 } 706 } else { 707 /* none */ 708 tve.detect = 0; 709 tve.output_mode = TV_OFF; 710 } 711 712 tve_set_tvout_mode(tve.output_mode); 713 714 /* clear interrupt */ 715 __raw_writel(CD_MON_END_INT | CD_LM_INT | CD_SM_INT, 716 tve.base + tve_regs->tve_stat_reg); 717 718 __raw_writel(int_ctl | CD_SM_INT | CD_LM_INT, 719 tve.base + tve_regs->tve_int_cont_reg); 720 721 if (old_detect != tve.detect) 722 sysfs_notify(&tve.pdev->dev.kobj, NULL, "headphone"); 723 724 dev_dbg(&tve.pdev->dev, "detect = %d mode = %d\n", 725 tve.detect, tve.output_mode); 726 done: 727 spin_unlock_irqrestore(&tve_lock, lock_flags); 728 return tve.detect; 729 } 643 ~ 647 TVE当前是disable的,所以不会做检测,直接返回tve.detect=0 650 ~655 应该使能CD_EN 657 ~ 669 每2ms检测一次tve_stat_reg,直到CD_MON_END_INT发生或者timeout 670 ~ 673 无CD_MON_END_INT中断发生,返回 675~710 根据tve_state_reg中的CD_CH_x_LM_ST和CD_CH_x_SM_ST来决定cable的插入状态 712 tve_set_tvout_mode是根据当前的cable 状态来调整tve out 模式 715 ~ 717 清空tve_stat_reg的cable detect状态位,写1清空 718 ~ 719 使能CD_SM_INT和CD_LM_INT,检测 cable的插拔 721 ~ 722 上报headphone事件给poll这个headphone文件描述符的进程
913 int tve_fb_event(struct notifier_block *nb, unsigned long val, void *v) 914 { 915 struct fb_event *event = v; 916 struct fb_info *fbi = event->info; 917 918 if (strcmp(fbi->fix.id, "DISP3 BG - DI1")) 919 return 0; 920 921 switch (val) { 922 case FB_EVENT_FB_REGISTERED: 923 pr_debug("fb registered event\n"); 924 if (tve_fbi != NULL) 925 break; 926 927 tve_fbi = fbi; 928 fb_add_videomode(&video_modes[0], &tve_modelist.list); 929 fb_add_videomode(&video_modes[1], &tve_modelist.list); 930 fb_add_videomode(&video_modes[2], &tve_modelist.list); 931 if (tve.revision == 2) { 932 fb_add_videomode(&video_modes[3], &tve_modelist.list); 933 fb_add_videomode(&video_modes[4], &tve_modelist.list); 934 fb_add_videomode(&video_modes[5], &tve_modelist.list); 935 fb_add_videomode(&video_modes[6], &tve_modelist.list); 936 fb_add_videomode(&video_modes[7], &tve_modelist.list); 937 fb_add_videomode(&video_modes[8], &tve_modelist.list); 938 if (cpu_is_mx53()) { 939 fb_add_videomode(&video_modes[9], &tve_modelist.list); 940 fb_add_videomode(&video_modes[10], &tve_modelist.list); 941 } 942 } 943 break; 944 case FB_EVENT_MODE_CHANGE: 945 { 946 if (tve_fbi != fbi) 947 break; 948 949 fbi->mode = (struct fb_videomode *)fb_match_mode(&tve_fbi->var, 950 &tve_modelist.list); 951 952 if (!fbi->mode) { 953 pr_warning("TVE: can not find mode for xres=%d, yres=%d\n", 954 fbi->var.xres, fbi->var.yres); 955 tve_disable(); 956 tve.cur_mode = TVOUT_FMT_OFF; 957 return 0; 958 } 959 960 pr_debug("TVE: fb mode change event: xres=%d, yres=%d\n", 961 fbi->mode->xres, fbi->mode->yres); 962 963 if (fb_mode_is_equal(fbi->mode, &video_modes[0])) { 964 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 965 tve_disable(); 966 tve_setup(TVOUT_FMT_NTSC); 967 if (tve.blank == FB_BLANK_UNBLANK) 968 tve_enable(); 969 } else if (fb_mode_is_equal(fbi->mode, &video_modes[1])) { 970 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 971 tve_disable(); 972 tve_setup(TVOUT_FMT_PAL); 973 if (tve.blank == FB_BLANK_UNBLANK) 974 tve_enable(); 975 } else if (fb_mode_is_equal(fbi->mode, &video_modes[2])) { 976 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 977 tve_disable(); 978 tve_setup(TVOUT_FMT_720P60); 979 if (tve.blank == FB_BLANK_UNBLANK) 980 tve_enable(); 981 } else if (fb_mode_is_equal(fbi->mode, &video_modes[3])) { 982 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 983 tve_disable(); 984 tve_setup(TVOUT_FMT_720P30); 985 if (tve.blank == FB_BLANK_UNBLANK) 986 tve_enable(); 987 } else if (fb_mode_is_equal(fbi->mode, &video_modes[4])) { 988 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 989 tve_disable(); 990 tve_setup(TVOUT_FMT_1080I60); 991 if (tve.blank == FB_BLANK_UNBLANK) 992 tve_enable(); 993 } else if (fb_mode_is_equal(fbi->mode, &video_modes[5])) { 994 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 995 tve_disable(); 996 tve_setup(TVOUT_FMT_1080I50); 997 if (tve.blank == FB_BLANK_UNBLANK) 998 tve_enable(); 999 } else if (fb_mode_is_equal(fbi->mode, &video_modes[6])) { 1000 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 1001 tve_disable(); 1002 tve_setup(TVOUT_FMT_1080P30); 1003 if (tve.blank == FB_BLANK_UNBLANK) 1004 tve_enable(); 1005 } else if (fb_mode_is_equal(fbi->mode, &video_modes[7])) { 1006 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 1007 tve_disable(); 1008 tve_setup(TVOUT_FMT_1080P25); 1009 if (tve.blank == FB_BLANK_UNBLANK) 1010 tve_enable(); 1011 } else if (fb_mode_is_equal(fbi->mode, &video_modes[8])) { 1012 tve_set_di_fmt(fbi, IPU_PIX_FMT_YUV444); 1013 tve_disable(); 1014 tve_setup(TVOUT_FMT_1080P24); 1015 if (tve.blank == FB_BLANK_UNBLANK) 1016 tve_enable(); 1017 } else if (fb_mode_is_equal(fbi->mode, &video_modes[9])) { 1018 tve_set_di_fmt(fbi, IPU_PIX_FMT_GBR24); 1019 tve_disable(); 1020 tve_setup(TVOUT_FMT_VGA_XGA); 1021 if (tve.blank == FB_BLANK_UNBLANK) { 1022 tve_enable(); 1023 ipu_set_vga_delay(fbi, 1421, 803); 1024 } 1025 } else if (fb_mode_is_equal(fbi->mode, &video_modes[10])) { 1026 tve_set_di_fmt(fbi, IPU_PIX_FMT_GBR24); 1027 tve_disable(); 1028 tve_setup(TVOUT_FMT_VGA_SXGA); 1029 if (tve.blank == FB_BLANK_UNBLANK) { 1030 tve_enable(); 1031 ipu_set_vga_delay(fbi, 1504, 1030); 1032 } 1033 } else { 1034 tve_disable(); 1035 tve_setup(TVOUT_FMT_OFF); 1036 } 1037 break; 1038 } 1039 case FB_EVENT_BLANK: 1040 if ((tve_fbi != fbi) || (fbi->mode == NULL)) 1041 return 0; 1042 1043 if (*((int *)event->data) == FB_BLANK_UNBLANK) { 1044 if (tve.blank != FB_BLANK_UNBLANK) { 1045 if (fb_mode_is_equal(fbi->mode, &video_modes[0])) { 1046 if (tve.cur_mode != TVOUT_FMT_NTSC) { 1047 tve_disable(); 1048 tve_setup(TVOUT_FMT_NTSC); 1049 } 1050 tve_enable(); 1051 } else if (fb_mode_is_equal(fbi->mode, 1052 &video_modes[1])) { 1053 if (tve.cur_mode != TVOUT_FMT_PAL) { 1054 tve_disable(); 1055 tve_setup(TVOUT_FMT_PAL); 1056 } 1057 tve_enable(); 1058 } else if (fb_mode_is_equal(fbi->mode, 1059 &video_modes[2])) { 1060 if (tve.cur_mode != TVOUT_FMT_720P60) { 1061 tve_disable(); 1062 tve_setup(TVOUT_FMT_720P60); 1063 } 1064 tve_enable(); 1065 } else if (fb_mode_is_equal(fbi->mode, 1066 &video_modes[3])) { 1067 if (tve.cur_mode != TVOUT_FMT_720P30) { 1068 tve_disable(); 1069 tve_setup(TVOUT_FMT_720P30); 1070 } 1071 tve_enable(); 1072 } else if (fb_mode_is_equal(fbi->mode, 1073 &video_modes[4])) { 1074 if (tve.cur_mode != TVOUT_FMT_1080I60) { 1075 tve_disable(); 1076 tve_setup(TVOUT_FMT_1080I60); 1077 } 1078 tve_enable(); 1079 } else if (fb_mode_is_equal(fbi->mode, 1080 &video_modes[5])) { 1081 if (tve.cur_mode != TVOUT_FMT_1080I50) { 1082 tve_disable(); 1083 tve_setup(TVOUT_FMT_1080I50); 1084 } 1085 tve_enable(); 1086 } else if (fb_mode_is_equal(fbi->mode, 1087 &video_modes[6])) { 1088 if (tve.cur_mode != TVOUT_FMT_1080P30) { 1089 tve_disable(); 1090 tve_setup(TVOUT_FMT_1080P30); 1091 } 1092 tve_enable(); 1093 } else if (fb_mode_is_equal(fbi->mode, 1094 &video_modes[7])) { 1095 if (tve.cur_mode != TVOUT_FMT_1080P25) { 1096 tve_disable(); 1097 tve_setup(TVOUT_FMT_1080P25); 1098 } 1099 tve_enable(); 1100 } else if (fb_mode_is_equal(fbi->mode, 1101 &video_modes[8])) { 1102 if (tve.cur_mode != TVOUT_FMT_1080P24) { 1103 tve_disable(); 1104 tve_setup(TVOUT_FMT_1080P24); 1105 } 1106 tve_enable(); 1107 } else if (fb_mode_is_equal(fbi->mode, 1108 &video_modes[9])) { 1109 if (tve.cur_mode != TVOUT_FMT_VGA_XGA) { 1110 tve_disable(); 1111 tve_setup(TVOUT_FMT_VGA_XGA); 1112 } 1113 tve_enable(); 1114 ipu_set_vga_delay(fbi, 1421, 803); 1115 } else if (fb_mode_is_equal(fbi->mode, 1116 &video_modes[10])) { 1117 if (tve.cur_mode != TVOUT_FMT_VGA_SXGA) { 1118 tve_disable(); 1119 tve_setup(TVOUT_FMT_VGA_SXGA); 1120 } 1121 tve_enable(); 1122 ipu_set_vga_delay(fbi, 1504, 1030); 1123 } else { 1124 tve_setup(TVOUT_FMT_OFF); 1125 } 1126 tve.blank = FB_BLANK_UNBLANK; 1127 } 1128 } else { 1129 tve_disable(); 1130 tve.blank = FB_BLANK_POWERDOWN; 1131 } 1132 break; 1133 case FB_EVENT_SUSPEND: 1134 tve_suspend(); 1135 break; 1136 case FB_EVENT_RESUME: 1137 tve_resume(fbi); 1138 break; 1139 } 1140 return 0; 1141 } 918 ~ 919 因为tve_fb_event被调用时不知道是不是tve的事件,如果不是,不做处理 922 ~ 943 FB_EVENT_FB_REGISTERED,那么要把NTSC PAL 720P加入到mode_list中,如果是rev2再加入一些mode,如果是mx53还支持XGA SXGA模式 944 ~ 1038 处理模式发生变化的情况 949 ~ 958 先检查新mode是否在tve_modelist中,不在的话则tve_disable 963 ~ 1032 1. 调用tve_set_di_fmt设置display input format; 2. disable tve; 3. tve_setup设置TVE 输出模式; 4.如果tve_fbi是UNBLANK的,那么还要调用tve_enable使能TVE 1033 ~ 1036 disable TVE,设置TVE 1039 case FB_EVENT_BLANK: 1040 if ((tve_fbi != fbi) || (fbi->mode == NULL)) 1041 return 0; 1042 1043 if (*((int *)event->data) == FB_BLANK_UNBLANK) { 1044 if (tve.blank != FB_BLANK_UNBLANK) { 1045 if (fb_mode_is_equal(fbi->mode, &video_modes[0])) { 1046 if (tve.cur_mode != TVOUT_FMT_NTSC) { 1047 tve_disable(); 1048 tve_setup(TVOUT_FMT_NTSC); 1049 } 1050 tve_enable(); 1051 } else if (fb_mode_is_equal(fbi->mode, 1052 &video_modes[1])) { 1053 if (tve.cur_mode != TVOUT_FMT_PAL) { 1054 tve_disable(); 1055 tve_setup(TVOUT_FMT_PAL); 1056 } 1057 tve_enable(); 1058 } else if (fb_mode_is_equal(fbi->mode, 1059 &video_modes[2])) { 1060 if (tve.cur_mode != TVOUT_FMT_720P60) { 1061 tve_disable(); 1062 tve_setup(TVOUT_FMT_720P60); 1063 } 1064 tve_enable(); 1065 } else if (fb_mode_is_equal(fbi->mode, 1066 &video_modes[3])) { 1067 if (tve.cur_mode != TVOUT_FMT_720P30) { 1068 tve_disable(); 1069 tve_setup(TVOUT_FMT_720P30); 1070 } 1071 tve_enable(); 1072 } else if (fb_mode_is_equal(fbi->mode, 1073 &video_modes[4])) { 1074 if (tve.cur_mode != TVOUT_FMT_1080I60) { 1075 tve_disable(); 1076 tve_setup(TVOUT_FMT_1080I60); 1077 } 1078 tve_enable(); 1079 } else if (fb_mode_is_equal(fbi->mode, 1080 &video_modes[5])) { 1081 if (tve.cur_mode != TVOUT_FMT_1080I50) { 1082 tve_disable(); 1083 tve_setup(TVOUT_FMT_1080I50); 1084 } 1085 tve_enable(); 1086 } else if (fb_mode_is_equal(fbi->mode, 1087 &video_modes[6])) { 1088 if (tve.cur_mode != TVOUT_FMT_1080P30) { 1089 tve_disable(); 1090 tve_setup(TVOUT_FMT_1080P30); 1091 } 1092 tve_enable(); 1093 } else if (fb_mode_is_equal(fbi->mode, 1094 &video_modes[7])) { 1095 if (tve.cur_mode != TVOUT_FMT_1080P25) { 1096 tve_disable(); 1097 tve_setup(TVOUT_FMT_1080P25); 1098 } 1099 tve_enable(); 1100 } else if (fb_mode_is_equal(fbi->mode, 1101 &video_modes[8])) { 1102 if (tve.cur_mode != TVOUT_FMT_1080P24) { 1103 tve_disable(); 1104 tve_setup(TVOUT_FMT_1080P24); 1105 } 1106 tve_enable(); 1107 } else if (fb_mode_is_equal(fbi->mode, 1108 &video_modes[9])) { 1109 if (tve.cur_mode != TVOUT_FMT_VGA_XGA) { 1110 tve_disable(); 1111 tve_setup(TVOUT_FMT_VGA_XGA); 1112 } 1113 tve_enable(); 1114 ipu_set_vga_delay(fbi, 1421, 803); 1115 } else if (fb_mode_is_equal(fbi->mode, 1116 &video_modes[10])) { 1117 if (tve.cur_mode != TVOUT_FMT_VGA_SXGA) { 1118 tve_disable(); 1119 tve_setup(TVOUT_FMT_VGA_SXGA); 1120 } 1121 tve_enable(); 1122 ipu_set_vga_delay(fbi, 1504, 1030); 1123 } else { 1124 tve_setup(TVOUT_FMT_OFF); 1125 } 1126 tve.blank = FB_BLANK_UNBLANK; 1127 } 1128 } else { 1129 tve_disable(); 1130 tve.blank = FB_BLANK_POWERDOWN; 1131 } 1132 break; 1133 case FB_EVENT_SUSPEND: 1134 tve_suspend(); 1135 break; 1136 case FB_EVENT_RESUME: 1137 tve_resume(fbi); 1138 break; 1139 } 1140 return 0; 1141 }
1128 ~ 1131 unblank操作,dsiable tve设置tve.blank为FB_BLANK_POWERDOWN 1043 ~ 1127 FB_BLANK_UNBLANK并且TVE当前状态不是FB_BLANK_UNBLANK,如果当前mode不是ffbi的当前模式,那么设置为当前模式,最后还要使能TVE
821 static inline void tve_set_di_fmt(struct fb_info *fbi, unsigned int fmt) 822 { 823 mm_segment_t old_fs; 824 825 if (fbi->fbops->fb_ioctl) { 826 old_fs = get_fs(); 827 set_fs(KERNEL_DS); 828 fbi->fbops->fb_ioctl(fbi, MXCFB_SET_DIFMT, (unsigned long)&fmt); 829 set_fs(old_fs); 830 } 831 } 该函数调用fbi->fbops->fb_ioctl设置 display format,由于fmt是内核空间,而fb_ioctl系统调用会确定&fmt是用户空间, 所以需要把当前的fs设置为内核空间,避开这个检查。参见http://blog.chinaunix.net/space.php?uid=20564848&do=blog&cuid=2097853
771 static irqreturn_t tve_detect_handler(int irq, void *data)
615 static void tve_disable(void)
578 static void tve_enable(void) 584 ~ 591 使能tve.clk,使能TVE以及TVE IPU clock 593 ~ 598 对于TVE VGA模式关闭cable detect 598 ~ 604 对于其他的模式使能cable detect
415 static int tve_setup(int mode) 428 ~ 454根据输出模式,设置时钟屏率,这里没搞明白这几个时钟的关系,以后再分析 458 ~ 467 设置parent clock, tve clk以及di1 clock的时钟频率 472 ~565 根据mode设置TVE的输出格式,这里没看明白的就是474行,传入的 mode为什么是YPBPR? 不是应该传入CVBS0吗,看不懂,觉得这里有问题,或者这里需要根据情况hard code;然后把输出模式设置到tve_com_conf_reg中 567 ~ 568 已经用完tve.clk,关闭它
333 static void tve_set_tvout_mode(int mode) 344 ~ 345 设置TVEV2_DATA_SRC 为BUS_1,这里还是hard code,其实我觉得也可以设置为BUS_2,那么数据就从IPU data bus2过来 346 设置input video的格式为YCbCr422 347 禁止progressive 到interlace的转换,我觉得如果是要得到NTSC PAL输出,最好使能它 350 ~ 355 根据给定的模式设置TV_OUT_MODE, 以及SYNC_CH_X_EN 小结: 分析后,如果想要实现自己的LCD+cvbs双屏输入,还需要定制一些参数,也许没看懂,做freescale的东西,真累。 (kickxxx) |