mx51 TVOUT分析

死磕k8s之calico-环境准备 序言: 本篇文章主要是列出了calico系列文章解析的环境以及准备工作。 环境 k8s: v1.19.3 iptables: v1.4.21 route: 2.10-alpha calico: v3.16.4 tcpdump calico使用的是ipip模式,calico默认是ipip模式 k8s没有高可用安装,1个master节点,2个work节点 k8s没有使用ipvs 工具安装 calicoctl安装 calicoctl是calico社区提供一个全局查看calico网络的工具,类似kube 阅读详情

转:http://blog.youkuaiyun.com/kickxxx/article/details/6777980

1397 static int __init enable_tve_setup(char *options)
1398 {
1399     g_enable_tve = true;
1400 
1401     return 1;
1402 }
1403 __setup("tve", enable_tve_setup);

一般情况,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)
1180 {
1181     u32 conf_reg;
1182     u32 rev = 0;
1183 
1184     /* find out TVE rev based on the base addr default value
1185      * can be used at the init/probe ONLY */
1186     conf_reg = __raw_readl(tve.base);
1187     switch (conf_reg) {
1188     case 0x00842000:
1189         rev = 1;
1190         break;
1191     case 0x00100000:
1192         rev = 2;
1193         break;
1194     }
1195     return rev;
1196 }

通过读取0xBASE_0000寄存器的初始缺省值来获取TVE的版本号


1147 static ssize_t show_headphone(struct device *dev,
1148         struct device_attribute *attr, char *buf)
1149 {
1150     int detect;
1151 
1152     if (!enabled) {
1153         strcpy(buf, "tve power off\n");
1154         return strlen(buf);
1155     }
1156 
1157     detect = tve_update_detect_status();
1158 
1159     if (detect == 0)
1160         strcpy(buf, "none\n");
1161     else if (detect == 1)
1162         strcpy(buf, "cvbs\n");
1163     else if (detect == 2)
1164         strcpy(buf, "headset\n");
1165     else if (detect == 3)
1166         strcpy(buf, "component\n");
1167     else
1168         strcpy(buf, "svideo\n");
1169 
1170     return strlen(buf);
1171 }
这个函数是一个sys接口的show函数,用来显示当前cable的插入状态,cat /sys/devices/platform/tve.0/headphone将显示相应状态

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)
 772 {
 773     u32 int_ctl = __raw_readl(tve.base + tve_regs->tve_int_cont_reg);
 774 
 775     /* disable INT first */
 776     int_ctl &= ~(CD_SM_INT | CD_LM_INT | CD_MON_END_INT);
 777     __raw_writel(int_ctl, tve.base + tve_regs->tve_int_cont_reg);
 778 
 779     __raw_writel(CD_MON_END_INT | CD_LM_INT | CD_SM_INT,
 780             tve.base + tve_regs->tve_stat_reg);
 781 
 782     schedule_delayed_work(&tve.cd_work, msecs_to_jiffies(1000));
 783 
 784     return IRQ_HANDLED;
 785 }


中断处理函数,首先disable INT清除中断状态位,然后清除掉tve_stat_reg中相应的状态位,这里我奇怪为什么要清除CD_MON_END_INT,因为tve_update_detect_status要使用这个标志呀


 615 static void tve_disable(void)
 616 {
 617     u32 reg;
 618     unsigned long lock_flags;
 619 
 620     spin_lock_irqsave(&tve_lock, lock_flags);
 621     if (enabled) {
 622         enabled = 0;
 623         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 624         __raw_writel(reg & ~TVE_ENABLE & ~TVE_IPU_CLK_ENABLE,
 625                 tve.base + tve_regs->tve_com_conf_reg);
 626         clk_disable(tve.clk);
 627         pr_debug("TVE power off.\n");
 628     }
 629     spin_unlock_irqrestore(&tve_lock, lock_flags);
 630 }
关闭TVE和TVE IPU clock,关闭tve.clk时钟,置位enable为0


 578 static void tve_enable(void)
 579 {
 580     u32 reg;
 581     unsigned long lock_flags;
 582 
 583     spin_lock_irqsave(&tve_lock, lock_flags);
 584     if (!enabled) {
 585         enabled = 1;
 586         clk_enable(tve.clk);
 587         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 588         __raw_writel(reg | TVE_IPU_CLK_ENABLE | TVE_ENABLE,
 589                     tve.base + tve_regs->tve_com_conf_reg);
 590         pr_debug("TVE power on.\n");
 591     }
 592 
 593     if (is_vga_mode()) {
 594         /* disable interrupt */
 595         pr_debug("TVE VGA disable cable detect.\n");
 596         __raw_writel(0xffffffff, tve.base + tve_regs->tve_stat_reg);
 597         __raw_writel(0, tve.base + tve_regs->tve_int_cont_reg);
 598     } else {
 599         /* enable interrupt */
 600         pr_debug("TVE TVE enable cable detect.\n");
 601         __raw_writel(0xffffffff, tve.base + tve_regs->tve_stat_reg);
 602         __raw_writel(CD_SM_INT | CD_LM_INT | CD_MON_END_INT,
 603                 tve.base + tve_regs->tve_int_cont_reg);
 604     }
 605 
 606     spin_unlock_irqrestore(&tve_lock, lock_flags);
 607 
 608     tve_dump_regs();
 609 }

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)
 416 {
 417     u32 reg;
 418     struct clk *tve_parent_clk;
 419     unsigned long parent_clock_rate = 216000000, di1_clock_rate = 27000000;
 420     unsigned long tve_clock_rate = 216000000;
 421     unsigned long lock_flags;
 422 
 423     if (tve.cur_mode == mode)
 424         return 0;
 425 
 426     spin_lock_irqsave(&tve_lock, lock_flags);
 427 
 428     switch (mode) {
 429     case TVOUT_FMT_PAL:
 430     case TVOUT_FMT_NTSC:
 431         parent_clock_rate = 216000000;
 432         di1_clock_rate = 27000000;
 433         break;
 434     case TVOUT_FMT_720P60:
 435     case TVOUT_FMT_1080I60:
 436     case TVOUT_FMT_1080I50:
 437     case TVOUT_FMT_720P30:
 438     case TVOUT_FMT_1080P30:
 439     case TVOUT_FMT_1080P25:
 440     case TVOUT_FMT_1080P24:
 441         parent_clock_rate = 297000000;
 442         tve_clock_rate = 297000000;
 443         di1_clock_rate = 74250000;
 444         break;
 445     case TVOUT_FMT_VGA_XGA:
 446         parent_clock_rate = 260000000;
 447         tve_clock_rate = 130000000;
 448         di1_clock_rate = 65000000;
 449         break;
 450     case TVOUT_FMT_VGA_SXGA:
 451         parent_clock_rate = 216000000;
 452         di1_clock_rate = 108000000;
 453         break;
 454     }
 455     if (enabled)
 456         clk_disable(tve.clk);
 457 
 458     tve_parent_clk = clk_get_parent(tve.clk);
 459 
 460     clk_set_rate(tve_parent_clk, parent_clock_rate);
 461 
 462     tve_clock_rate = clk_round_rate(tve.clk, tve_clock_rate);
 463     clk_set_rate(tve.clk, tve_clock_rate);
 464 
 465     clk_enable(tve.clk);
 466     di1_clock_rate = clk_round_rate(tve.di_clk, di1_clock_rate);
 467     clk_set_rate(tve.di_clk, di1_clock_rate);
 468 
 469     tve.cur_mode = mode;
 470 
 471     /* select output video format */
 472     if (mode == TVOUT_FMT_PAL) {
 473         tve_disable_vga_mode();
 474         tve_set_tvout_mode(YPBPR);
 475         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 476         reg = (reg & ~TVE_STAND_MASK) | TVE_PAL_STAND;
 477         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 478         pr_debug("TVE: change to PAL video\n");
 479     } else if (mode == TVOUT_FMT_NTSC) {
 480         tve_disable_vga_mode();
 481         tve_set_tvout_mode(YPBPR);
 482         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 483         reg = (reg & ~TVE_STAND_MASK) | TVE_NTSC_STAND;
 484         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 485         pr_debug("TVE: change to NTSC video\n");
 486     } else if (mode == TVOUT_FMT_720P60) {
 487         tve_disable_vga_mode();
 488         if (!_is_tvout_mode_hd_compatible()) {
 489             tve_set_tvout_mode(YPBPR);
 490             pr_debug("The TV out mode is HD incompatible. Setting to YPBPR.");
 491         }
 492         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 493         reg = (reg & ~TVE_STAND_MASK) | TVE_HD720P60_STAND;
 494         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 495         pr_debug("TVE: change to 720P60 video\n");
 496     } else if (mode == TVOUT_FMT_720P30) {
 497         tve_disable_vga_mode();
 498         if (!_is_tvout_mode_hd_compatible()) {
 499             tve_set_tvout_mode(YPBPR);
 500             pr_debug("The TV out mode is HD incompatible. Setting to YPBPR.");
 501         }
 502         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 503         reg = (reg & ~TVE_STAND_MASK) | TVE_HD720P30_STAND;
 504         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 505         pr_debug("TVE: change to 720P30 video\n");
 506     } else if (mode == TVOUT_FMT_1080I60) {
 507         tve_disable_vga_mode();
 508         if (!_is_tvout_mode_hd_compatible()) {
 509             tve_set_tvout_mode(YPBPR);
 510             pr_debug("The TV out mode is HD incompatible. Setting to YPBPR.");
 511         }
 512         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 513         reg = (reg & ~TVE_STAND_MASK) | TVE_HD1080I60_STAND;
 514         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 515         pr_debug("TVE: change to 1080I60 video\n");
 516     } else if (mode == TVOUT_FMT_1080I50) {
 517         tve_disable_vga_mode();
 518         if (!_is_tvout_mode_hd_compatible()) {
 519             tve_set_tvout_mode(YPBPR);
 520             pr_debug("The TV out mode is HD incompatible. Setting to YPBPR.");
 521         }
 522         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 523         reg = (reg & ~TVE_STAND_MASK) | TVE_HD1080I50_STAND;
 524         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 525         pr_debug("TVE: change to 1080I50 video\n");
 526     } else if (mode == TVOUT_FMT_1080P30) {
 527         tve_disable_vga_mode();
 528         if (!_is_tvout_mode_hd_compatible()) {
 529             tve_set_tvout_mode(YPBPR);
 530             pr_debug("The TV out mode is HD incompatible. Setting to YPBPR.");
 531         }
 532         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 533         reg = (reg & ~TVE_STAND_MASK) | TVE_HD1080P30_STAND;
 534         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 535         pr_debug("TVE: change to 1080P30 video\n");
 536     } else if (mode == TVOUT_FMT_1080P25) {
 537         tve_disable_vga_mode();
 538         if (!_is_tvout_mode_hd_compatible()) {
 539             tve_set_tvout_mode(YPBPR);
 540             pr_debug("The TV out mode is HD incompatible. Setting to YPBPR.");
 541         }
 542         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 543         reg = (reg & ~TVE_STAND_MASK) | TVE_HD1080P25_STAND;
 544         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 545         pr_debug("TVE: change to 1080P25 video\n");
 546     } else if (mode == TVOUT_FMT_1080P24) {
 547         tve_disable_vga_mode();
 548         if (!_is_tvout_mode_hd_compatible()) {
 549             tve_set_tvout_mode(YPBPR);
 550             pr_debug("The TV out mode is HD incompatible. Setting to YPBPR.");
 551         }
 552         reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 553         reg = (reg & ~TVE_STAND_MASK) | TVE_HD1080P24_STAND;
 554         __raw_writel(reg, tve.base + tve_regs->tve_com_conf_reg);
 555         pr_debug("TVE: change to 1080P24 video\n");
 556     } else if ((mode == TVOUT_FMT_VGA_XGA) || (mode == TVOUT_FMT_VGA_SXGA)) {
 557         /* do not need cable detect */
 558         tve_setup_vga();
 559         pr_debug("TVE: change to VGA video\n");
 560     } else if (mode == TVOUT_FMT_OFF) {
 561         __raw_writel(0x0, tve.base + tve_regs->tve_com_conf_reg);
 562         pr_debug("TVE: change to OFF video\n");
 563     } else {
 564         pr_debug("TVE: no such video format.\n");
 565     }
 566 
 567     if (!enabled)
 568         clk_disable(tve.clk);
 569 
 570     spin_unlock_irqrestore(&tve_lock, lock_flags);
 571     return 0;
 572 }

428 ~ 454根据输出模式,设置时钟屏率,这里没搞明白这几个时钟的关系,以后再分析
455和465 先关闭再使能,为了保证所有情况下都打开tve.clk,以便下面对tve的操作。

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)
 334 {
 335     u32 conf_reg;
 336 
 337     /* clear sync_ch and tvout_mode fields */
 338     conf_reg = __raw_readl(tve.base + tve_regs->tve_com_conf_reg);
 339     conf_reg &= ~(tve_reg_fields->sync_ch_mask |
 340                 tve_reg_fields->tvout_mode_mask);
 341 
 342     conf_reg = conf_reg & ~TVE_DAC_SAMPRATE_MASK;
 343     if (tve.revision == 2) {
 344         conf_reg = (conf_reg & ~TVEV2_DATA_SRC_MASK) |
 345             TVEV2_DATA_SRC_BUS_1;
 346         conf_reg = conf_reg & ~TVEV2_INP_VIDEO_FORM;
 347         conf_reg = conf_reg & ~TVEV2_P2I_CONV_EN;
 348     }
 349 
 350     conf_reg |=
 351         mode << tve_reg_fields->
 352         tvout_mode_offset | tvout_mode_to_channel_map[mode] <<
 353         tve_reg_fields->sync_ch_offset;
 354     __raw_writel(conf_reg, tve.base + tve_regs->tve_com_conf_reg);
 355 }

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的东西,真累。

MTGS与3D高斯泼溅:如何用多轨迹数据重建自动驾驶场景(附代码解析) 本文深入解析了MTGS(多轨迹高斯泼溅)技术在自动驾驶场景重建中的工程实践。该方法通过分层场景表示,巧妙融合多轨迹数据,利用3D高斯泼溅技术统一处理静态几何与动态物体,有效解决了复杂环境下的重建难题。文章结合代码,详细阐述了其实现框架、损失函数设计及优化策略,为构建高保真数字孪生场景提供了实用指南。 阅读详情

相关推荐

从Axure转Figma?这篇编组、缩放、圆角、评论的对比指南帮你无缝切换

本文为资深Axure设计师提供了向Figma无缝迁移的实战指南。文章深度对比了编组、缩放、圆角、评论等核心操作,重点解析了Figma独特的自动布局、组件系统和实时协作功能,旨在帮助用户快速适应新工具,实现设计思维与工作效率的跃迁。

tomato的博客 851

The Differences Between Successful People and Unsuccessful People

A few weeks ago I received a postcard in the mail from the CEO of Petra Coach, the creator of Align Software and a fellow member of Entrepreneurs Organization. I've never met him, but Andy Bailey an

6万+

Hyper-V虚拟交换机实战:外部/内部/专用网络配置全解析

本文全面解析Hyper-V虚拟交换机的三种核心类型:外部、内部和专用网络。详细阐述了外部交换机如何让虚拟机融入物理网络,内部交换机如何构建宿主机与虚拟机的私有通道,以及专用交换机如何实现虚拟机间的完全隔离。通过实战配置步骤、IP规划建议和OpenWRT软路由案例,帮助用户根据需求灵活部署,并特别强调了外部交换机配置中“允许管理操作系统共享此网络适配器”这一关键选项的重要性,以避免宿主机断网。

weixin_29218963的博客 544

P3992 [BJOI2017]开车

题目链接 题目描述 有 nnn 辆车,分别在 a1,a2,…,ana_1, a_2, \ldots , a_na1​,a2​,…,an​ 位置和 nnn 个加油站,分别在 b1,b2,…,bnb_1, b_2, \ldots ,b_nb1​,b2​,…,bn​ 位置。 每个加油站只能支持一辆车的加油,所以你要把这些车开到不同的加油站加油。一个车从 xxx 位置开到 yyy 位置的代价为 ∣x−y∣|x-y|∣x−y∣,问如何安排车辆,使得代价之和最小。 同时你有 qqq 个操作,每次操作会修改第 iii 辆

sky123博客 2万+

手把手教你读懂蓝牙BQB射频测试报告:以PRBS9为例的实战分析

本文以蓝牙BQB射频测试中的PRBS9信号为例,提供了一份实战分析指南。文章深入解读了输出功率、调制特性、邻道泄漏等核心测试项,并分享了信号分析仪操作技巧、测试环境搭建要点及设备选型建议,旨在帮助工程师精准解读报告,高效定位问题,确保产品顺利通过认证。

weixin_29289821的博客 261

手把手教你学Simulink--移动机器人多轮协同场景实例:基于Simulink的双轮差速PMSM轮毂电机协同驱动仿真

本文介绍了基于Simulink的双轮差速PMSM轮毂电机协同驱动仿真系统。针对移动机器人存在的电机参数不一致、负载分配不均等问题,提出主从同步+力矩补偿的协同控制策略。通过搭建包含运动学模型、PMSM电机模型和矢量控制器的仿真系统,实现了速度同步误差<0.005m/s、轨迹跟踪误差<0.8cm、能耗降低12.5%的优化效果。文章详细阐述了建模步骤、核心算法实现和性能验证,为移动机器人动力系统设计提供了实用参考方案。

MHD0815的博客 133

流媒体开发之-音悦台TV解析

由于工作问题写博客不能连贯,很多个人开发者开发播放器的时候,基本上都是提供播放功能,没有提供网上资源,比较维护是很麻烦的,我们可以使用网上资源,最近业余在搞音乐部分,对于资源部分我也是使用网上现有的资源,比如音悦台里面有很多TV,我们可以解析他们的网页内容。下面就是解析其中一个网页的TV 首先确定你TV要实现的内容,封装一个类内容如下: package com.pigvideo.model;

jwzhangjie的专栏 3万+

【论文复现】——基于欧式聚类的车载点云道路提取

针对车载激光点云道路信息提取的问题,提出了一种基于欧式聚类的道路提取方法。首先通过统计滤波去除噪点以免对后续处理结果产生影响,然后用坡度滤波去除路坎点,使道路边界与人行道、绿化带等与路坎相连的地物形成10~25 cm的高程阶跃,最后用欧式聚类将路面点云与其他地物点云聚类为一簇或多簇并保留道路簇,从而实现道路点云的精确提取。

点云侠的博客 1135

mx51 TVOUT分析 .

1397 static int __init enable_tve_setup(char *options) 1398 { 1399     g_enable_tve = true; 1400 1401     return 1; 1402 } 1403 __setup("tve", enable_tve_setup); 一般情况,freescale会推荐在kernel命令行参

gjy938815的专栏 1169

Android 14.0 首次开机默认授予app运行时权限(去掉运行时授权弹窗)

在14.0的系统rom产品定制化开发中,在6.0以后对于权限的申请,都需要动态申请,所以会在系统首次启动后,在app的首次运行时, 会弹出授权窗口,会让用户手动授予app运行时权限,在由于系统产品开发需要要求默认授予app运行时权限,不需要用户默认授予运行时弹窗,所以需要在首次开机默认授予所有app运行时权限

安卓兼职framework和app工程师的博客 2531

【时时三省】tessy 进入调试模式 教程

山不在高,有仙则名。水不在深,有龙则灵。----优快云 时时三省。

时时三省的博客 771

mx51的三个framebuffer,mxc_ipuv3_fb.c分析

mx51支持三个framebuffer:fb0, fb1, fb2 /dev/graphics/fb0,/dev/graphics/fb1: 一个作为系统的主framebuffer,另外一个作为TVOUT输出的framebuffer,缺省情况下,fb0做primary(也就是用来在primary LCD显示UI),fb1做secondary(也就是用来在TVOUT输出上显示数据)。

jack_a8的专栏 3568

基于 YOLOv26 的金属表面缺陷检测系统:智能视觉质检方案

摘要: 基于YOLOv26的金属表面缺陷检测系统采用深度学习技术,实现对划痕、裂纹、腐蚀等8类常见缺陷的自动化检测。系统通过数据增强预处理和YOLOv26模型的高精度识别能力,具备多类别分类、实时推理和强鲁棒性特点,适用于不同金属材质与光照条件。架构包含数据采集、预处理、YOLOv26检测和后处理模块,代码实现采用PyTorch框架,支持训练数据增强与标准化处理,为工业质检提供高效智能解决方案。

一键难忘的博客 589

MX51 V4L2 output 驱动

之前调试MXC V4L2驱动一直没有注意到output/mxc_v4l2_output.c这个文件,因为capture/*.c已经提供了still capture, stream capture, 以及overlay,所以没仔细的去看mxc_v4l2_output.c提供的功能,直到前几天负责维护overlay hal的同事提出打开了overlay hal /dev/video16这个设备节点,才

kickxxx的专栏 6283

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

草稿

@TOC 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 全新的界面设计 ,将会带来全...

Smiorld的博客 2万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

vivi 使用

 ivi就象DOS一样可以配置板子的硬件资源,DOS有命令行,vivi也有,接下来我们就熟悉一下这些命令,感觉命令有一些多,不过经常用到的不是很多,大家只要多操作几次就会非常上手拉.4.1 part命令·part show 显示分区信息·part add partname part_start_addr part_leng 0 添加分区·part del partname 删除分区·part

vitolee的专栏 1074

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

有趣的计算机隐藏文件方法

要隐藏计算机中的文件或文件夹,方法很多。最最简单的无非右键属性隐藏。 之前发现一个很有趣的隐藏方法,比较兴奋,简单分享一下: 首先,建一个文件夹,把你要隐藏的文件放在里面,至于放什么,大家都懂的。 比如说你建的文件夹叫 xxx ,给这个文件夹加个扩展名(后缀) xxx.{20D04FE0-3AEA-1069-A2D8-08002B30309D} 把它放在桌面 你会惊奇滴发现,原来的文件

自助者天助~ 1万+

Flutter TV应用的开发尝试

Flutter TV应用的开发尝试开发的运行效果图开发的主要难点Flutter TV应用开发按键监听Flutter TV应用开发焦点处理Flutter TV应用开发焦点框效果处理 Flutter主要是进行移动应用开发外,最近尝试了下Flutter开发TV应用。虽然写出来了,效果也还可以,体验流畅,自动适配。不过开发成本还是挺高的,按键监听、焦点处理和焦点框处理比较麻烦,由于Google官方并没有...

持续学习中 2万+

在线影视网站分享(持续更新)

TV212影院TvTv2影视80S影院爱视频。

swsmj的博客 4万+

Codeforces Round 992 (Div. 2)(A-E)

补题,于2024.12.19添加E题

Vcoistnt的博客 697

Android为TV端助力:RecyclerView更新数据时焦点丢失

1.adapter的setHasStableIds设置成true 2.重写adapter的getItemId方法 @Override public long getItemId(int position) { return position; }3.mRecyclerView.setItemAnimator(null); 转载于:https://w...

weixin_30606669的博客 306

新版293神马tv搭建服务,最新UI

,界面非常美观流畅,外面最低卖500。4.播放器支持自定义名称和顺序。,有效防止地区反诈误拦截.

u011167983的博客 1447
上一篇: bayer, yuv, RGB转换方法
下一篇: mx51 TVOUT cvbs双屏支持
evilcode
博客等级 码龄20年 307粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值