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

Configure Feed

Select the types of activity you want to include in your feed.

media: aspeed: Correct values for detected timing

Correct timing's fp/sync/bp value based on the information below.
It should be noticed that the calculation formula should be changed
per sync polarity.

The sequence of signal: sync - backporch - video data - frontporch

The following registers start counting from sync's rising edge:
1. VR090: frame edge's left and right
2. VR094: frame edge's top and bottom
3. VR09C: counting from sync's rising edge to falling edge

[Vertical timing]
+--+ +-------------------+ +--+
| | | v i d e o | | |
+--+ +-----+ +-----+ +---+
vsync+--+
frame_top+--------+
frame_bottom+----------------------------+

+-------------------+
| v i d e o |
+--+ +-----+ +-----+ +---+
| | | |
+--+ +--+
vsync+-------------------------------+
frame_top+-----+
frame_bottom+-------------------------+

[Horizontal timing]
+--+ +-------------------+ +--+
| | | v i d e o | | |
+--+ +-----+ +-----+ +---+
hsync+--+
frame_left+--------+
frame_right+----------------------------+

+-------------------+
| v i d e o |
+--+ +-----+ +-----+ +---+
| | | |
+--+ +--+
hsync+-------------------------------+
frame_left+-----+
frame_right+-------------------------+

Ex. 1920x1200@60 whose vsync polarity is negative
VR098: c4d3efff, VR09C: 04cc001f
v-total = 0x4D3 (VR098[27:16]) = 1235
v-sync = 0x4CC (VR09C[27:16]) = 1228

[hverkuil: drop unused variable mds]

Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Jammy Huang and committed by
Mauro Carvalho Chehab
a922a0cb 26aea93b

+97 -13
+97 -13
drivers/media/platform/aspeed-video.c
··· 803 803 video->max_compressed_size); 804 804 } 805 805 806 + /* 807 + * Update v4l2_bt_timings per current status. 808 + * frame_top/frame_bottom/frame_left/frame_right need to be ready. 809 + * 810 + * The following registers start counting from sync's rising edge: 811 + * 1. VR090: frame edge's left and right 812 + * 2. VR094: frame edge's top and bottom 813 + * 3. VR09C: counting from sync's rising edge to falling edge 814 + * 815 + * [Vertical timing] 816 + * +--+ +-------------------+ +--+ 817 + * | | | v i d e o | | | 818 + * +--+ +-----+ +-----+ +---+ 819 + * vsync+--+ 820 + * frame_top+--------+ 821 + * frame_bottom+----------------------------+ 822 + * 823 + * +-------------------+ 824 + * | v i d e o | 825 + * +--+ +-----+ +-----+ +---+ 826 + * | | | | 827 + * +--+ +--+ 828 + * vsync+-------------------------------+ 829 + * frame_top+-----+ 830 + * frame_bottom+-------------------------+ 831 + * 832 + * [Horizontal timing] 833 + * +--+ +-------------------+ +--+ 834 + * | | | v i d e o | | | 835 + * +--+ +-----+ +-----+ +---+ 836 + * hsync+--+ 837 + * frame_left+--------+ 838 + * frame_right+----------------------------+ 839 + * 840 + * +-------------------+ 841 + * | v i d e o | 842 + * +--+ +-----+ +-----+ +---+ 843 + * | | | | 844 + * +--+ +--+ 845 + * hsync+-------------------------------+ 846 + * frame_left+-----+ 847 + * frame_right+-------------------------+ 848 + * 849 + * @v: the struct of aspeed_video 850 + * @det: v4l2_bt_timings to be updated. 851 + */ 852 + static void aspeed_video_get_timings(struct aspeed_video *v, 853 + struct v4l2_bt_timings *det) 854 + { 855 + u32 mds, sync, htotal, vtotal, vsync, hsync; 856 + 857 + mds = aspeed_video_read(v, VE_MODE_DETECT_STATUS); 858 + sync = aspeed_video_read(v, VE_SYNC_STATUS); 859 + htotal = aspeed_video_read(v, VE_H_TOTAL_PIXELS); 860 + vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds); 861 + vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync); 862 + hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync); 863 + 864 + /* 865 + * This is a workaround for polarity detection. 866 + * Because ast-soc counts sync from sync's rising edge, the reg value 867 + * of sync would be larger than video's active area if negative. 868 + */ 869 + if (vsync > det->height) 870 + det->polarities &= ~V4L2_DV_VSYNC_POS_POL; 871 + else 872 + det->polarities |= V4L2_DV_VSYNC_POS_POL; 873 + if (hsync > det->width) 874 + det->polarities &= ~V4L2_DV_HSYNC_POS_POL; 875 + else 876 + det->polarities |= V4L2_DV_HSYNC_POS_POL; 877 + 878 + if (det->polarities & V4L2_DV_VSYNC_POS_POL) { 879 + det->vbackporch = v->frame_top - vsync; 880 + det->vfrontporch = vtotal - v->frame_bottom; 881 + det->vsync = vsync; 882 + } else { 883 + det->vbackporch = v->frame_top; 884 + det->vfrontporch = vsync - v->frame_bottom; 885 + det->vsync = vtotal - vsync; 886 + } 887 + 888 + if (det->polarities & V4L2_DV_HSYNC_POS_POL) { 889 + det->hbackporch = v->frame_left - hsync; 890 + det->hfrontporch = htotal - v->frame_right; 891 + det->hsync = hsync; 892 + } else { 893 + det->hbackporch = v->frame_left; 894 + det->hfrontporch = hsync - v->frame_right; 895 + det->hsync = htotal - hsync; 896 + } 897 + } 898 + 806 899 #define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags) 807 900 808 901 static void aspeed_video_get_resolution(struct aspeed_video *video) ··· 903 810 bool invalid_resolution = true; 904 811 int rc; 905 812 int tries = 0; 906 - u32 mds; 907 813 u32 src_lr_edge; 908 814 u32 src_tb_edge; 909 - u32 sync; 910 - u32 htotal; 911 815 struct v4l2_bt_timings *det = &video->detected_timings; 912 816 913 817 det->width = MIN_WIDTH; ··· 948 858 949 859 src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET); 950 860 src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET); 951 - mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS); 952 - sync = aspeed_video_read(video, VE_SYNC_STATUS); 953 - htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS); 954 861 955 862 video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge); 956 863 video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge); 957 - det->vfrontporch = video->frame_top; 958 - det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) - 959 - video->frame_bottom; 960 - det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync); 864 + 961 865 if (video->frame_top > video->frame_bottom) 962 866 continue; 963 867 964 868 video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge); 965 869 video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge); 966 - det->hfrontporch = video->frame_left; 967 - det->hbackporch = htotal - video->frame_right; 968 - det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync); 870 + 969 871 if (video->frame_left > video->frame_right) 970 872 continue; 971 873 ··· 972 890 det->height = (video->frame_bottom - video->frame_top) + 1; 973 891 det->width = (video->frame_right - video->frame_left) + 1; 974 892 video->v4l2_input_status = 0; 893 + 894 + aspeed_video_get_timings(video, det); 975 895 976 896 /* 977 897 * Enable mode-detect watchdog, resolution-change watchdog and