SimyriK

kernel/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c

Jun 19th, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 37.18 KB | None | 0 0
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include "rockchip-hdmi.h"
  3.  
  4. static const struct hdmi_video_timing hdmi_mode[] = {
  5.     {
  6.         .mode = {
  7.             .name = "720x480i@60Hz",
  8.             .refresh = 60,
  9.             .xres = 720,
  10.             .yres = 480,
  11.             .pixclock = 27000000,
  12.             .left_margin = 57,
  13.             .right_margin = 19,
  14.             .upper_margin = 15,
  15.             .lower_margin = 4,
  16.             .hsync_len = 62,
  17.             .vsync_len = 3,
  18.             .sync = 0,
  19.             .vmode = FB_VMODE_INTERLACED,
  20.             .flag = 0,
  21.         },
  22.         .vic = HDMI_720X480I_60HZ_4_3,
  23.         .vic_2nd = HDMI_720X480I_60HZ_16_9,
  24.         .pixelrepeat = 2,
  25.         .interface = OUT_P888,
  26.     },
  27.     {
  28.         .mode = {
  29.             .name = "720x576i@50Hz",
  30.             .refresh = 50,
  31.             .xres = 720,
  32.             .yres = 576,
  33.             .pixclock = 27000000,
  34.             .left_margin = 69,
  35.             .right_margin = 12,
  36.             .upper_margin = 19,
  37.             .lower_margin = 2,
  38.             .hsync_len = 63,
  39.             .vsync_len = 3,
  40.             .sync = 0,
  41.             .vmode = FB_VMODE_INTERLACED,
  42.             .flag = 0,
  43.         },
  44.         .vic = HDMI_720X576I_50HZ_4_3,
  45.         .vic_2nd = HDMI_720X576I_50HZ_16_9,
  46.         .pixelrepeat = 2,
  47.         .interface = OUT_P888,
  48.     },
  49.     {
  50.         .mode = {
  51.             .name = "720x480p@60Hz",
  52.             .refresh = 60,
  53.             .xres = 720,
  54.             .yres = 480,
  55.             .pixclock = 27000000,
  56.             .left_margin = 60,
  57.             .right_margin = 16,
  58.             .upper_margin = 30,
  59.             .lower_margin = 9,
  60.             .hsync_len = 62,
  61.             .vsync_len = 6,
  62.             .sync = 0,
  63.             .vmode = 0,
  64.             .flag = 0,
  65.         },
  66.         .vic = HDMI_720X480P_60HZ_4_3,
  67.         .vic_2nd = HDMI_720X480P_60HZ_16_9,
  68.         .pixelrepeat = 1,
  69.         .interface = OUT_P888,
  70.     },
  71.     {
  72.         .mode = {
  73.             .name = "720x576p@50Hz",
  74.             .refresh = 50,
  75.             .xres = 720,
  76.             .yres = 576,
  77.             .pixclock = 27000000,
  78.             .left_margin = 68,
  79.             .right_margin = 12,
  80.             .upper_margin = 39,
  81.             .lower_margin = 5,
  82.             .hsync_len = 64,
  83.             .vsync_len = 5,
  84.             .sync = 0,
  85.             .vmode = 0,
  86.             .flag = 0,
  87.         },
  88.         .vic = HDMI_720X576P_50HZ_4_3,
  89.         .vic_2nd = HDMI_720X576P_50HZ_16_9,
  90.         .pixelrepeat = 1,
  91.         .interface = OUT_P888,
  92.     },
  93.     {
  94.         .mode = {
  95.             .name = "1280x720p@24Hz",
  96.             .refresh = 24,
  97.             .xres = 1280,
  98.             .yres = 720,
  99.             .pixclock = 59400000,
  100.             .left_margin = 220,
  101.             .right_margin = 1760,
  102.             .upper_margin = 20,
  103.             .lower_margin = 5,
  104.             .hsync_len = 40,
  105.             .vsync_len = 5,
  106.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  107.             .vmode = 0,
  108.             .flag = 0,
  109.         },
  110.         .vic = HDMI_1280X720P_24HZ,
  111.         .vic_2nd = HDMI_1280X720P_24HZ_21_9,
  112.         .pixelrepeat = 1,
  113.         .interface = OUT_P888,
  114.     },
  115.     {
  116.         .mode = {
  117.             .name = "1280x720p@25Hz",
  118.             .refresh = 25,
  119.             .xres = 1280,
  120.             .yres = 720,
  121.             .pixclock = 74250000,
  122.             .left_margin = 220,
  123.             .right_margin = 2420,
  124.             .upper_margin = 20,
  125.             .lower_margin = 5,
  126.             .hsync_len = 40,
  127.             .vsync_len = 5,
  128.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  129.             .vmode = 0,
  130.             .flag = 0,
  131.         },
  132.         .vic = HDMI_1280X720P_25HZ,
  133.         .vic_2nd = HDMI_1280X720P_25HZ_21_9,
  134.         .pixelrepeat = 1,
  135.         .interface = OUT_P888,
  136.     },
  137.     {
  138.         .mode = {
  139.             .name = "1280x720p@30Hz",
  140.             .refresh = 30,
  141.             .xres = 1280,
  142.             .yres = 720,
  143.             .pixclock = 74250000,
  144.             .left_margin = 220,
  145.             .right_margin = 1760,
  146.             .upper_margin = 20,
  147.             .lower_margin = 5,
  148.             .hsync_len = 40,
  149.             .vsync_len = 5,
  150.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  151.             .vmode = 0,
  152.             .flag = 0,
  153.         },
  154.         .vic = HDMI_1280X720P_30HZ,
  155.         .vic_2nd = HDMI_1280X720P_30HZ_21_9,
  156.         .pixelrepeat = 1,
  157.         .interface = OUT_P888,
  158.     },
  159.     {
  160.         .mode = {
  161.             .name = "1280x720p@50Hz",
  162.             .refresh = 50,
  163.             .xres = 1280,
  164.             .yres = 720,
  165.             .pixclock = 74250000,
  166.             .left_margin = 220,
  167.             .right_margin = 440,
  168.             .upper_margin = 20,
  169.             .lower_margin = 5,
  170.             .hsync_len = 40,
  171.             .vsync_len = 5,
  172.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  173.             .vmode = 0,
  174.             .flag = 0,
  175.         },
  176.         .vic = HDMI_1280X720P_50HZ,
  177.         .vic_2nd = HDMI_1280X720P_50HZ_21_9,
  178.         .pixelrepeat = 1,
  179.         .interface = OUT_P888,
  180.     },
  181.     {
  182.         .mode = {
  183.             .name = "1280x720p@60Hz",
  184.             .refresh = 60,
  185.             .xres = 1280,
  186.             .yres = 720,
  187.             .pixclock = 74250000,
  188.             .left_margin = 220,
  189.             .right_margin = 110,
  190.             .upper_margin = 20,
  191.             .lower_margin = 5,
  192.             .hsync_len = 40,
  193.             .vsync_len = 5,
  194.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  195.             .vmode = 0,
  196.             .flag = 0,
  197.         },
  198.         .vic = HDMI_1280X720P_60HZ,
  199.         .vic_2nd = HDMI_1280X720P_60HZ_21_9,
  200.         .pixelrepeat = 1,
  201.         .interface = OUT_P888,
  202.     },
  203.     {
  204.         .mode = {
  205.             .name = "1280x800p@60Hz",
  206.             .refresh = 60,
  207.             .xres = 1280,
  208.             .yres = 800,
  209.             .pixclock = 83500000,
  210.             .left_margin = 200,
  211.             .right_margin = 72,
  212.             .upper_margin = 22,
  213.             .lower_margin = 3,
  214.             .hsync_len = 128,
  215.             .vsync_len = 6,
  216.             .sync = 0,
  217.             .vmode = 0,
  218.             .flag = 0,
  219.         },
  220.         .vic = HDMI_VIDEO_DMT | 10,
  221.         .vic_2nd = 0,
  222.         .pixelrepeat = 1,
  223.         .interface = OUT_P888,
  224.     },
  225.     {
  226.         .mode = {
  227.             .name = "1920x1080i@50Hz",
  228.             .refresh = 50,
  229.             .xres = 1920,
  230.             .yres = 1080,
  231.             .pixclock = 74250000,
  232.             .left_margin = 148,
  233.             .right_margin = 528,
  234.             .upper_margin = 15,
  235.             .lower_margin = 2,
  236.             .hsync_len = 44,
  237.             .vsync_len = 5,
  238.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  239.             .vmode = FB_VMODE_INTERLACED,
  240.             .flag = 0,
  241.         },
  242.         .vic = HDMI_1920X1080I_50HZ,
  243.         .vic_2nd = 0,
  244.         .pixelrepeat = 1,
  245.         .interface = OUT_P888,
  246.     },
  247.     {
  248.         .mode = {
  249.             .name = "1920x1080i@60Hz",
  250.             .refresh = 60,
  251.             .xres = 1920,
  252.             .yres = 1080,
  253.             .pixclock = 74250000,
  254.             .left_margin = 148,
  255.             .right_margin = 88,
  256.             .upper_margin = 15,
  257.             .lower_margin = 2,
  258.             .hsync_len = 44,
  259.             .vsync_len = 5,
  260.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  261.             .vmode = FB_VMODE_INTERLACED,
  262.             .flag = 0,
  263.         },
  264.         .vic = HDMI_1920X1080I_60HZ,
  265.         .vic_2nd = 0,
  266.         .pixelrepeat = 1,
  267.         .interface = OUT_P888,
  268.     },
  269.     {
  270.         .mode = {
  271.             .name = "1920x1080p@24Hz",
  272.             .refresh = 24,
  273.             .xres = 1920,
  274.             .yres = 1080,
  275.             .pixclock = 74250000,
  276.             .left_margin = 148,
  277.             .right_margin = 638,
  278.             .upper_margin = 36,
  279.             .lower_margin = 4,
  280.             .hsync_len = 44,
  281.             .vsync_len = 5,
  282.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  283.             .vmode = 0,
  284.             .flag = 0,
  285.         },
  286.         .vic = HDMI_1920X1080P_24HZ,
  287.         .vic_2nd = HDMI_1920X1080P_24HZ_21_9,
  288.         .pixelrepeat = 1,
  289.         .interface = OUT_P888,
  290.     },
  291.     {
  292.         .mode = {
  293.             .name = "1920x1080p@25Hz",
  294.             .refresh = 25,
  295.             .xres = 1920,
  296.             .yres = 1080,
  297.             .pixclock = 74250000,
  298.             .left_margin = 148,
  299.             .right_margin = 528,
  300.             .upper_margin = 36,
  301.             .lower_margin = 4,
  302.             .hsync_len = 44,
  303.             .vsync_len = 5,
  304.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  305.             .vmode = 0,
  306.             .flag = 0,
  307.         },
  308.         .vic = HDMI_1920X1080P_25HZ,
  309.         .vic_2nd = HDMI_1920X1080P_25HZ_21_9,
  310.         .pixelrepeat = 1,
  311.         .interface = OUT_P888,
  312.     },
  313.     {
  314.         .mode = {
  315.             .name = "1920x1080p@30Hz",
  316.             .refresh = 30,
  317.             .xres = 1920,
  318.             .yres = 1080,
  319.             .pixclock = 74250000,
  320.             .left_margin = 148,
  321.             .right_margin = 88,
  322.             .upper_margin = 36,
  323.             .lower_margin = 4,
  324.             .hsync_len = 44,
  325.             .vsync_len = 5,
  326.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  327.             .vmode = 0,
  328.             .flag = 0,
  329.         },
  330.         .vic = HDMI_1920X1080P_30HZ,
  331.         .vic_2nd = HDMI_1920X1080P_30HZ_21_9,
  332.         .pixelrepeat = 1,
  333.         .interface = OUT_P888,
  334.     },
  335.     {
  336.         .mode = {
  337.             .name = "1920x1080p@50Hz",
  338.             .refresh = 50,
  339.             .xres = 1920,
  340.             .yres = 1080,
  341.             .pixclock = 148500000,
  342.             .left_margin = 148,
  343.             .right_margin = 528,
  344.             .upper_margin = 36,
  345.             .lower_margin = 4,
  346.             .hsync_len = 44,
  347.             .vsync_len = 5,
  348.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  349.             .vmode = 0,
  350.             .flag = 0,
  351.         },
  352.         .vic = HDMI_1920X1080P_50HZ,
  353.         .vic_2nd = HDMI_1920X1080P_50HZ_21_9,
  354.         .pixelrepeat = 1,
  355.         .interface = OUT_P888,
  356.     },
  357.     {
  358.         .mode = {
  359.             .name = "1920x1080p@60Hz",
  360.             .refresh = 60,
  361.             .xres = 1920,
  362.             .yres = 1080,
  363.             .pixclock = 148500000,
  364.             .left_margin = 148,
  365.             .right_margin = 88,
  366.             .upper_margin = 36,
  367.             .lower_margin = 4,
  368.             .hsync_len = 44,
  369.             .vsync_len = 5,
  370.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  371.             .vmode = 0,
  372.             .flag = 0,
  373.         },
  374.         .vic = HDMI_1920X1080P_60HZ,
  375.         .vic_2nd = HDMI_1920X1080P_60HZ_21_9,
  376.         .pixelrepeat = 1,
  377.         .interface = OUT_P888,
  378.     },
  379.     {
  380.         .mode = {
  381.             .name = "3840x2160p@24Hz",
  382.             .refresh = 24,
  383.             .xres = 3840,
  384.             .yres = 2160,
  385.             .pixclock = 297000000,
  386.             .left_margin = 296,
  387.             .right_margin = 1276,
  388.             .upper_margin = 72,
  389.             .lower_margin = 8,
  390.             .hsync_len = 88,
  391.             .vsync_len = 10,
  392.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  393.             .vmode = 0,
  394.             .flag = 0,
  395.         },
  396.         .vic = HDMI_3840X2160P_24HZ,
  397.         .vic_2nd = HDMI_3840X2160P_24HZ_21_9,
  398.         .pixelrepeat = 1,
  399.         .interface = OUT_P888,
  400.     },
  401.     {
  402.         .mode = {
  403.             .name = "3840x2160p@25Hz",
  404.             .refresh = 25,
  405.             .xres = 3840,
  406.             .yres = 2160,
  407.             .pixclock = 297000000,
  408.             .left_margin = 296,
  409.             .right_margin = 1056,
  410.             .upper_margin = 72,
  411.             .lower_margin = 8,
  412.             .hsync_len = 88,
  413.             .vsync_len = 10,
  414.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  415.             .vmode = 0,
  416.             .flag = 0,
  417.         },
  418.         .vic = HDMI_3840X2160P_25HZ,
  419.         .vic_2nd = HDMI_3840X2160P_25HZ_21_9,
  420.         .pixelrepeat = 1,
  421.         .interface = OUT_P888,
  422.     },
  423.     {
  424.         .mode = {
  425.             .name = "3840x2160p@30Hz",
  426.             .refresh = 30,
  427.             .xres = 3840,
  428.             .yres = 2160,
  429.             .pixclock = 297000000,
  430.             .left_margin = 296,
  431.             .right_margin = 176,
  432.             .upper_margin = 72,
  433.             .lower_margin = 8,
  434.             .hsync_len = 88,
  435.             .vsync_len = 10,
  436.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  437.             .vmode = 0,
  438.             .flag = 0,
  439.         },
  440.         .vic = HDMI_3840X2160P_30HZ,
  441.         .vic_2nd = HDMI_3840X2160P_30HZ_21_9,
  442.         .pixelrepeat = 1,
  443.         .interface = OUT_P888,
  444.     },
  445.     {
  446.         .mode = {
  447.             .name = "4096x2160p@24Hz",
  448.             .refresh = 24,
  449.             .xres = 4096,
  450.             .yres = 2160,
  451.             .pixclock = 297000000,
  452.             .left_margin = 296,
  453.             .right_margin = 1020,
  454.             .upper_margin = 72,
  455.             .lower_margin = 8,
  456.             .hsync_len = 88,
  457.             .vsync_len = 10,
  458.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  459.             .vmode = 0,
  460.             .flag = 0,
  461.         },
  462.         .vic = HDMI_4096X2160P_24HZ,
  463.         .vic_2nd = 0,
  464.         .pixelrepeat = 1,
  465.         .interface = OUT_P888,
  466.     },
  467.     {
  468.         .mode = {
  469.             .name = "4096x2160p@25Hz",
  470.             .refresh = 25,
  471.             .xres = 4096,
  472.             .yres = 2160,
  473.             .pixclock = 297000000,
  474.             .left_margin = 128,
  475.             .right_margin = 968,
  476.             .upper_margin = 72,
  477.             .lower_margin = 8,
  478.             .hsync_len = 88,
  479.             .vsync_len = 10,
  480.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  481.             .vmode = 0,
  482.             .flag = 0,
  483.         },
  484.         .vic = HDMI_4096X2160P_25HZ,
  485.         .vic_2nd = 0,
  486.         .pixelrepeat = 1,
  487.         .interface = OUT_P888,
  488.     },
  489.     {
  490.         .mode = {
  491.             .name = "4096x2160p@30Hz",
  492.             .refresh = 30,
  493.             .xres = 4096,
  494.             .yres = 2160,
  495.             .pixclock = 297000000,
  496.             .left_margin = 128,
  497.             .right_margin = 88,
  498.             .upper_margin = 72,
  499.             .lower_margin = 8,
  500.             .hsync_len = 88,
  501.             .vsync_len = 10,
  502.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  503.             .vmode = 0,
  504.             .flag = 0,
  505.         },
  506.         .vic = HDMI_4096X2160P_30HZ,
  507.         .vic_2nd = 0,
  508.         .pixelrepeat = 1,
  509.         .interface = OUT_P888,
  510.     },
  511.     {
  512.         .mode = {
  513.             .name = "3840x2160p@50Hz",
  514.             .refresh = 50,
  515.             .xres = 3840,
  516.             .yres = 2160,
  517.             .pixclock = 594000000,
  518.             .left_margin = 296,
  519.             .right_margin = 1056,
  520.             .upper_margin = 72,
  521.             .lower_margin = 8,
  522.             .hsync_len = 88,
  523.             .vsync_len = 10,
  524.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  525.             .vmode = 0,
  526.             .flag = 0,
  527.         },
  528.         .vic = HDMI_3840X2160P_50HZ,
  529.         .vic_2nd = HDMI_3840X2160P_50HZ_21_9,
  530.         .pixelrepeat = 1,
  531.         .interface = OUT_P888,
  532.     },
  533.     {
  534.         .mode = {
  535.             .name = "3840x2160p@60Hz",
  536.             .refresh = 60,
  537.             .xres = 3840,
  538.             .yres = 2160,
  539.             .pixclock = 594000000,
  540.             .left_margin = 296,
  541.             .right_margin = 176,
  542.             .upper_margin = 72,
  543.             .lower_margin = 8,
  544.             .hsync_len = 88,
  545.             .vsync_len = 10,
  546.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  547.             .vmode = 0,
  548.             .flag = 0,
  549.         },
  550.         .vic = HDMI_3840X2160P_60HZ,
  551.         .vic_2nd = HDMI_3840X2160P_60HZ_21_9,
  552.         .pixelrepeat = 1,
  553.         .interface = OUT_P888,
  554.     },
  555.     {
  556.         .mode = {
  557.             .name = "4096x2160p@50Hz",
  558.             .refresh = 50,
  559.             .xres = 4096,
  560.             .yres = 2160,
  561.             .pixclock = 594000000,
  562.             .left_margin = 128,
  563.             .right_margin = 968,
  564.             .upper_margin = 72,
  565.             .lower_margin = 8,
  566.             .hsync_len = 88,
  567.             .vsync_len = 10,
  568.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  569.             .vmode = 0,
  570.             .flag = 0,
  571.         },
  572.         .vic = HDMI_4096X2160P_50HZ,
  573.         .vic_2nd = 0,
  574.         .pixelrepeat = 1,
  575.         .interface = OUT_P888,
  576.     },
  577.     {
  578.         .mode = {
  579.             .name = "4096x2160p@60Hz",
  580.             .refresh = 60,
  581.             .xres = 4096,
  582.             .yres = 2160,
  583.             .pixclock = 594000000,
  584.             .left_margin = 128,
  585.             .right_margin = 88,
  586.             .upper_margin = 72,
  587.             .lower_margin = 8,
  588.             .hsync_len = 88,
  589.             .vsync_len = 10,
  590.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  591.             .vmode = 0,
  592.             .flag = 0,
  593.         },
  594.         .vic = HDMI_4096X2160P_60HZ,
  595.         .vic_2nd = 0,
  596.         .pixelrepeat = 1,
  597.         .interface = OUT_P888,
  598.     },
  599.     {
  600.         .mode = {
  601.             .name = "800x600p@60Hz",
  602.             .refresh = 60,
  603.             .xres = 800,
  604.             .yres = 600,
  605.             .pixclock = 40000000,
  606.             .left_margin = 88,
  607.             .right_margin = 40,
  608.             .upper_margin = 23,
  609.             .lower_margin = 1,
  610.             .hsync_len = 128,
  611.             .vsync_len = 4,
  612.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  613.             .vmode = 0,
  614.             .flag = 0,
  615.         },
  616.         .vic = HDMI_VIDEO_DMT | 1,
  617.         .vic_2nd = 0,
  618.         .pixelrepeat = 1,
  619.         .interface = OUT_P888,
  620.     },
  621.     {
  622.         .mode = {
  623.             .name = "1024x768p@60Hz",
  624.             .refresh = 60,
  625.             .xres = 1024,
  626.             .yres = 768,
  627.             .pixclock = 65000000,
  628.             .left_margin = 160,
  629.             .right_margin = 24,
  630.             .upper_margin = 29,
  631.             .lower_margin = 3,
  632.             .hsync_len = 136,
  633.             .vsync_len = 6,
  634.             .sync = 0,
  635.             .vmode = 0,
  636.             .flag = 0,
  637.         },
  638.         .vic = HDMI_VIDEO_DMT | 2,
  639.         .vic_2nd = 0,
  640.         .pixelrepeat = 1,
  641.         .interface = OUT_P888,
  642.     },
  643.     {
  644.         .mode = {
  645.             .name = "1280x960p@60Hz",
  646.             .refresh = 60,
  647.             .xres = 1280,
  648.             .yres = 960,
  649.             .pixclock = 108000000,
  650.             .left_margin = 312,
  651.             .right_margin = 96,
  652.             .upper_margin = 36,
  653.             .lower_margin = 1,
  654.             .hsync_len = 112,
  655.             .vsync_len = 3,
  656.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  657.             .vmode = 0,
  658.             .flag = 0,
  659.         },
  660.         .vic = HDMI_VIDEO_DMT | 3,
  661.         .vic_2nd = 0,
  662.         .pixelrepeat = 1,
  663.         .interface = OUT_P888,
  664.     },
  665.     {
  666.         .mode = {
  667.             .name = "1280x1024p@60Hz",
  668.             .refresh = 60,
  669.             .xres = 1280,
  670.             .yres = 1024,
  671.             .pixclock = 108000000,
  672.             .left_margin = 248,
  673.             .right_margin = 48,
  674.             .upper_margin = 38,
  675.             .lower_margin = 1,
  676.             .hsync_len = 112,
  677.             .vsync_len = 3,
  678.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  679.             .vmode = 0,
  680.             .flag = 0,
  681.         },
  682.         .vic = HDMI_VIDEO_DMT | 4,
  683.         .vic_2nd = 0,
  684.         .pixelrepeat = 1,
  685.         .interface = OUT_P888,
  686.     },
  687.     {
  688.         .mode = {
  689.             .name = "1360x768p@60Hz",
  690.             .refresh = 60,
  691.             .xres = 1360,
  692.             .yres = 768,
  693.             .pixclock = 85500000,
  694.             .left_margin = 256,
  695.             .right_margin = 64,
  696.             .upper_margin = 18,
  697.             .lower_margin = 3,
  698.             .hsync_len = 112,
  699.             .vsync_len = 6,
  700.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  701.             .vmode = 0,
  702.             .flag = 0,
  703.         },
  704.         .vic = HDMI_VIDEO_DMT | 5,
  705.         .vic_2nd = 0,
  706.         .pixelrepeat = 1,
  707.         .interface = OUT_P888,
  708.     },
  709.     {
  710.         .mode = {
  711.             .name = "1366x768p@60Hz",
  712.             .refresh = 60,
  713.             .xres = 1366,
  714.             .yres = 768,
  715.             .pixclock = 85500000,
  716.             .left_margin = 213,
  717.             .right_margin = 70,
  718.             .upper_margin = 24,
  719.             .lower_margin = 3,
  720.             .hsync_len = 143,
  721.             .vsync_len = 3,
  722.             .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  723.             .vmode = 0,
  724.             .flag = 0,
  725.         },
  726.         .vic = HDMI_VIDEO_DMT | 6,
  727.         .vic_2nd = 0,
  728.         .pixelrepeat = 1,
  729.         .interface = OUT_P888,
  730.     },
  731.     {
  732.         .mode = {
  733.             .name = "1440x900p@60Hz",
  734.             .refresh = 60,
  735.             .xres = 1440,
  736.             .yres = 900,
  737.             .pixclock = 106500000,
  738.             .left_margin = 232,
  739.             .right_margin = 80,
  740.             .upper_margin = 25,
  741.             .lower_margin = 3,
  742.             .hsync_len = 152,
  743.             .vsync_len = 6,
  744.             .sync = FB_SYNC_VERT_HIGH_ACT,
  745.             .vmode = 0,
  746.             .flag = 0,
  747.         },
  748.         .vic = HDMI_VIDEO_DMT | 7,
  749.         .vic_2nd = 0,
  750.         .pixelrepeat = 1,
  751.         .interface = OUT_P888,
  752.     },
  753.     {
  754.         .mode = {
  755.             .name = "1600x900p@60Hz",
  756.             .refresh = 60,
  757.             .xres = 1600,
  758.             .yres = 900,
  759.             .pixclock = 108000000,
  760.             .left_margin = 96,
  761.             .right_margin = 24,
  762.             .upper_margin = 96,
  763.             .lower_margin = 1,
  764.             .hsync_len = 80,
  765.             .vsync_len = 3,
  766.             .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  767.             .vmode = 0,
  768.             .flag = 0,
  769.         },
  770.         .vic = HDMI_VIDEO_DMT | 8,
  771.         .vic_2nd = 0,
  772.         .pixelrepeat = 1,
  773.         .interface = OUT_P888,
  774.     },
  775.     {
  776.         .mode = {
  777.             .name = "1680x1050@60Hz",
  778.             .refresh = 60,
  779.             .xres = 1680,
  780.             .yres = 1050,
  781.             .pixclock = 146250000,
  782.             .left_margin = 280,
  783.             .right_margin = 104,
  784.             .upper_margin = 30,
  785.             .lower_margin = 3,
  786.             .hsync_len = 176,
  787.             .vsync_len = 6,
  788.             .sync = FB_SYNC_VERT_HIGH_ACT,
  789.             .vmode = 0,
  790.             .flag = 0,
  791.         },
  792.         .vic = HDMI_VIDEO_DMT | 9,
  793.         .vic_2nd = 0,
  794.         .pixelrepeat = 1,
  795.         .interface = OUT_P888,
  796.     },
  797.     {
  798.         .mode = {
  799.             .name = "1440x1280@60Hz",
  800.             .refresh = 60,
  801.             .xres = 1440,
  802.             .yres = 1280,
  803.             .pixclock = 148500000,
  804.             .left_margin = 84,
  805.             .right_margin = 360,
  806.             .upper_margin = 8,
  807.             .lower_margin = 10,
  808.             .hsync_len = 20,
  809.             .vsync_len = 2,
  810.             .sync = 0,
  811.             .vmode = 0,
  812.             .flag = 0,
  813.         },
  814.         .vic = HDMI_VIDEO_DISCRETE_VR | 1,
  815.         .vic_2nd = 0,
  816.         .pixelrepeat = 1,
  817.         .interface = OUT_P888,
  818.     },
  819.     {
  820.         /* AUO 3.81 */
  821.         .mode = {
  822.             .name = "2160x1200@75Hz",
  823.             .refresh = 75,
  824.             .xres = 2160,
  825.             .yres = 1200,
  826.             .pixclock = 245000000,
  827.             .left_margin = 100,
  828.             .right_margin = 420,
  829.             .upper_margin = 3,
  830.             .lower_margin = 6,
  831.             .hsync_len = 32,
  832.             .vsync_len = 3,
  833.             .sync = 0,
  834.             .vmode = 0,
  835.             .flag = 0,
  836.         },
  837.         .vic = HDMI_VIDEO_DISCRETE_VR | 3,
  838.         .vic_2nd = 0,
  839.         .pixelrepeat = 1,
  840.         .interface = OUT_P888,
  841.     },
  842.     {
  843.         /* sharp 2.89 */
  844.         .mode = {
  845.             .name = "2880x1440@75Hz",
  846.             .refresh = 75,
  847.             .xres = 2880,
  848.             .yres = 1440,
  849.             .pixclock = 340000000,
  850.             .left_margin = 100,
  851.             .right_margin = 50,
  852.             .upper_margin = 8,
  853.             .lower_margin = 6,
  854.             .hsync_len = 50,
  855.             .vsync_len = 1,
  856.             .sync = 0,
  857.             .vmode = 0,
  858.             .flag = 0,
  859.         },
  860.         .vic = HDMI_VIDEO_DISCRETE_VR | 4,
  861.         .vic_2nd = 0,
  862.         .pixelrepeat = 1,
  863.         .interface = OUT_P888,
  864.     },
  865.     {
  866.         /* RAYKEN 5.46 */
  867.         .mode = {
  868.             .name = "1440x2560@60Hz",
  869.             .refresh = 60,
  870.             .xres = 1440,
  871.             .yres = 2560,
  872.             .pixclock = 268500000,
  873.             .left_margin = 50,
  874.             .right_margin = 200,
  875.             .upper_margin = 20,
  876.             .lower_margin = 20,
  877.             .hsync_len = 20,
  878.             .vsync_len = 10,
  879.             .sync = 0,
  880.             .vmode = 0,
  881.             .flag = 0,
  882.         },
  883.         .vic = HDMI_VIDEO_DISCRETE_VR | 5,
  884.         .vic_2nd = 0,
  885.         .pixelrepeat = 1,
  886.         .interface = OUT_P888,
  887.     },
  888.     {
  889.         /* samsung */
  890.         .mode = {
  891.             .name = "1440x2560@70Hz",
  892.             .refresh = 70,
  893.             .xres = 1440,
  894.             .yres = 2560,
  895.             .pixclock = 285000000,
  896.             .left_margin = 40,
  897.             .right_margin = 80,
  898.             .upper_margin = 2,
  899.             .lower_margin = 6,
  900.             .hsync_len = 20,
  901.             .vsync_len = 8,
  902.             .sync = 0,
  903.             .vmode = 0,
  904.             .flag = 0,
  905.         },
  906.         .vic = HDMI_VIDEO_DISCRETE_VR | 6,
  907.         .vic_2nd = 0,
  908.         .pixelrepeat = 1,
  909.         .interface = OUT_P888,
  910.     },
  911. };
  912.  
  913. static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi)
  914. {
  915.     int i, vic, colorimetry;
  916.     struct fb_videomode *mode;
  917.  
  918.     if (!screen || !hdmi)
  919.         return HDMI_ERROR_FALSE;
  920.  
  921.     if (hdmi->vic == 0)
  922.         hdmi->vic = hdmi->property->defaultmode;
  923.  
  924.     if (hdmi->edid_auto_support) {
  925.         if ((hdmi->vic & HDMI_VIDEO_DMT) ||
  926.             (hdmi->vic & HDMI_VIDEO_DISCRETE_VR)) {
  927.             if (hdmi->prop.value.vic)
  928.                 vic = hdmi->prop.value.vic;
  929.             else
  930.                 vic = hdmi->vic;
  931.         } else {
  932.             vic = hdmi->vic & HDMI_VIC_MASK;
  933.         }
  934.     } else {
  935.         if ((hdmi->vic & HDMI_VIDEO_DMT) ||
  936.             (hdmi->vic & HDMI_VIDEO_DISCRETE_VR))
  937.             vic = hdmi->vic;
  938.         else
  939.             vic = hdmi->vic & HDMI_VIC_MASK;
  940.     }
  941.  
  942.     for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  943.         if (hdmi_mode[i].vic == vic ||
  944.             hdmi_mode[i].vic_2nd == vic)
  945.             break;
  946.     }
  947.     if (i == ARRAY_SIZE(hdmi_mode))
  948.         return HDMI_ERROR_FALSE;
  949.  
  950.     memset(screen, 0, sizeof(struct rk_screen));
  951.  
  952.     /* screen type & face */
  953.     screen->type = SCREEN_HDMI;
  954.     colorimetry = hdmi->video.colorimetry;
  955.     mode = (struct fb_videomode *)&hdmi_mode[i].mode;
  956.     if (hdmi->video.color_input == HDMI_COLOR_RGB_0_255) {
  957.         screen->color_mode = COLOR_RGB;
  958.     } else if (colorimetry > HDMI_COLORIMETRY_EXTEND_ADOBE_RGB) {
  959.         screen->color_mode = COLOR_YCBCR_BT2020;
  960.         if (hdmi->video.eotf == EOTF_ST_2084)
  961.             screen->data_space = 1;
  962.     } else if (colorimetry == HDMI_COLORIMETRY_NO_DATA) {
  963.         if (mode->xres > 720 && mode->yres > 576)
  964.             screen->color_mode = COLOR_YCBCR_BT709;
  965.         else
  966.             screen->color_mode = COLOR_YCBCR;
  967.     } else if (colorimetry == HDMI_COLORIMETRY_SMTPE_170M) {
  968.         screen->color_mode = COLOR_YCBCR;
  969.     } else {
  970.         screen->color_mode = COLOR_YCBCR_BT709;
  971.     }
  972.  
  973.     if (hdmi->vic & HDMI_VIDEO_YUV420) {
  974.         if (hdmi->video.color_output_depth == 10)
  975.             screen->face = OUT_YUV_420_10BIT;
  976.         else
  977.             screen->face = OUT_YUV_420;
  978.     } else {
  979.         if (hdmi->video.color_output_depth == 10)
  980.             screen->face = OUT_P101010;
  981.         else
  982.             screen->face = hdmi_mode[i].interface;
  983.     }
  984.     screen->pixelrepeat = hdmi_mode[i].pixelrepeat - 1;
  985.     screen->mode = *mode;
  986.     if (hdmi->video.format_3d == HDMI_3D_FRAME_PACKING) {
  987.         screen->mode.pixclock = 2 * mode->pixclock;
  988.         if (mode->vmode == 0) {
  989.             screen->mode.yres = 2 * mode->yres +
  990.                     mode->upper_margin +
  991.                     mode->lower_margin +
  992.                     mode->vsync_len;
  993.         } else {
  994.             screen->mode.yres = 2 * mode->yres +
  995.                         3 * (mode->upper_margin +
  996.                          mode->lower_margin +
  997.                          mode->vsync_len) + 2;
  998.             screen->mode.vmode = 0;
  999.         }
  1000.     }
  1001.     /* Pin polarity */
  1002.     if (FB_SYNC_HOR_HIGH_ACT & mode->sync)
  1003.         screen->pin_hsync = 1;
  1004.     else
  1005.         screen->pin_hsync = 0;
  1006.     if (FB_SYNC_VERT_HIGH_ACT & mode->sync)
  1007.         screen->pin_vsync = 1;
  1008.     else
  1009.         screen->pin_vsync = 0;
  1010.  
  1011.     screen->pin_den = 0;
  1012.     screen->pin_dclk = 1;
  1013.  
  1014.     /* Swap rule */
  1015.     if (hdmi->soctype > HDMI_SOC_RK312X &&
  1016.         screen->color_mode > COLOR_RGB &&
  1017.         (screen->face == OUT_P888 ||
  1018.          screen->face == OUT_P101010))
  1019.         screen->swap_rb = 1;
  1020.     else
  1021.         screen->swap_rb = 0;
  1022.     screen->swap_rg = 0;
  1023.     screen->swap_gb = 0;
  1024.     screen->swap_delta = 0;
  1025.     screen->swap_dumy = 0;
  1026.  
  1027.     /* Operation function*/
  1028.     screen->init = NULL;
  1029.     screen->standby = NULL;
  1030.  
  1031.     screen->overscan.left = hdmi->xscale;
  1032.     screen->overscan.top = hdmi->yscale;
  1033.     screen->overscan.right = hdmi->xscale;
  1034.     screen->overscan.bottom = hdmi->yscale;
  1035.  
  1036.     screen->width = hdmi->prop.value.width;
  1037.     screen->height = hdmi->prop.value.height;
  1038.     pr_info("%s:line=%d %d %d %d %d %d %d %d %d\n",
  1039.         __func__, __LINE__, screen->mode.xres, screen->mode.yres,
  1040.         screen->mode.left_margin, screen->mode.right_margin,
  1041.         screen->mode.upper_margin, screen->mode.lower_margin,
  1042.         screen->mode.hsync_len, screen->mode.vsync_len);
  1043.  
  1044.     return 0;
  1045. }
  1046.  
  1047. /**
  1048.  * hdmi_find_best_mode: find the video mode nearest to input vic
  1049.  * @hdmi:
  1050.  * @vic: input vic
  1051.  *
  1052.  * NOTES:
  1053.  * If vic is zero, return the high resolution video mode vic.
  1054.  */
  1055. int hdmi_find_best_mode(struct hdmi *hdmi, int vic)
  1056. {
  1057.     struct list_head *pos, *head = &hdmi->edid.modelist;
  1058.     struct display_modelist *modelist = NULL;
  1059.     int found = 0;
  1060.  
  1061.     if (vic) {
  1062.         list_for_each(pos, head) {
  1063.             modelist =
  1064.                 list_entry(pos,
  1065.                        struct display_modelist, list);
  1066.             if (modelist->vic == vic) {
  1067.                 found = 1;
  1068.                 break;
  1069.             }
  1070.         }
  1071.     }
  1072.     if ((!vic || !found) && head->next != head) {
  1073.         /* If parse edid error, we select default mode; */
  1074.         if (hdmi->edid.specs &&
  1075.             hdmi->edid.specs->modedb_len)
  1076.             modelist = list_entry(head->next,
  1077.                           struct display_modelist, list);
  1078.         else
  1079.             return hdmi->property->defaultmode;
  1080.     }
  1081.  
  1082.     if (modelist)
  1083.         return modelist->vic;
  1084.     else
  1085.         return 0;
  1086. }
  1087.  
  1088. /**
  1089.  * hdmi_set_lcdc: switch lcdc mode to required video mode
  1090.  * @hdmi:
  1091.  *
  1092.  * NOTES:
  1093.  *
  1094.  */
  1095. int hdmi_set_lcdc(struct hdmi *hdmi)
  1096. {
  1097.     int rc = 0;
  1098.     struct rk_screen screen;
  1099.  
  1100.     rc = hdmi_set_info(&screen, hdmi);
  1101.     if (!rc)
  1102.         rk_fb_switch_screen(&screen, 1, hdmi->lcdc->id);
  1103.     return rc;
  1104. }
  1105.  
  1106. /**
  1107.  * hdmi_videomode_compare - compare 2 videomodes
  1108.  * @mode1: first videomode
  1109.  * @mode2: second videomode
  1110.  *
  1111.  * RETURNS:
  1112.  * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2
  1113.  */
  1114. static int hdmi_videomode_compare(const struct fb_videomode *mode1,
  1115.                   const struct fb_videomode *mode2)
  1116. {
  1117.     if (mode1->xres > mode2->xres)
  1118.         return 1;
  1119.  
  1120.     if (mode1->xres == mode2->xres) {
  1121.         if (mode1->yres > mode2->yres)
  1122.             return 1;
  1123.         if (mode1->yres == mode2->yres) {
  1124.             if (mode1->vmode < mode2->vmode)
  1125.                 return 1;
  1126.             if (mode1->pixclock > mode2->pixclock)
  1127.                 return 1;
  1128.             if (mode1->pixclock == mode2->pixclock) {
  1129.                 if (mode1->refresh > mode2->refresh)
  1130.                     return 1;
  1131.                 if (mode1->refresh == mode2->refresh) {
  1132.                     if (mode2->flag > mode1->flag)
  1133.                         return 1;
  1134.                     if (mode2->flag < mode1->flag)
  1135.                         return -1;
  1136.                     if (mode2->vmode > mode1->vmode)
  1137.                         return 1;
  1138.                     if (mode2->vmode == mode1->vmode)
  1139.                         return 0;
  1140.                 }
  1141.             }
  1142.         }
  1143.     }
  1144.     return -1;
  1145. }
  1146.  
  1147. /**
  1148.  * hdmi_add_vic - add entry to modelist according vic
  1149.  * @vic: vic to be added
  1150.  * @head: struct list_head of modelist
  1151.  *
  1152.  * NOTES:
  1153.  * Will only add unmatched mode entries
  1154.  */
  1155. int hdmi_add_vic(int vic, struct list_head *head)
  1156. {
  1157.     struct list_head *pos;
  1158.     struct display_modelist *modelist;
  1159.     int found = 0, v;
  1160.  
  1161.     /*pr_info("%s vic %d\n", __FUNCTION__, vic);*/
  1162.     if (vic == 0)
  1163.         return -1;
  1164.  
  1165.     if (vic & HDMI_VIDEO_YUV420) {
  1166.         v = vic & 0xff;
  1167.         if (v != HDMI_3840X2160P_50HZ &&
  1168.             v != HDMI_3840X2160P_60HZ &&
  1169.             v != HDMI_4096X2160P_50HZ &&
  1170.             v != HDMI_4096X2160P_60HZ &&
  1171.             v != HDMI_3840X2160P_50HZ_21_9 &&
  1172.             v != HDMI_3840X2160P_60HZ_21_9) {
  1173.             return -1;
  1174.         }
  1175.     }
  1176.  
  1177.     list_for_each(pos, head) {
  1178.         modelist = list_entry(pos, struct display_modelist, list);
  1179.         v = modelist->vic;
  1180.         if (v == vic) {
  1181.             found = 1;
  1182.             break;
  1183.         }
  1184.     }
  1185.     if (!found) {
  1186.         modelist = kmalloc(sizeof(*modelist),
  1187.                    GFP_KERNEL);
  1188.  
  1189.         if (!modelist)
  1190.             return -ENOMEM;
  1191.         memset(modelist, 0, sizeof(struct display_modelist));
  1192.         modelist->vic = vic;
  1193.         list_add_tail(&modelist->list, head);
  1194.     }
  1195.     return 0;
  1196. }
  1197.  
  1198. /**
  1199.  * hdmi_add_videomode: adds videomode entry to modelist
  1200.  * @mode: videomode to be added
  1201.  * @head: struct list_head of modelist
  1202.  *
  1203.  * NOTES:
  1204.  * Will only add unmatched mode entries
  1205.  */
  1206. static int hdmi_add_videomode(const struct fb_videomode *mode,
  1207.                   struct list_head *head)
  1208. {
  1209.     struct list_head *pos;
  1210.     struct display_modelist *modelist, *modelist_new;
  1211.     struct fb_videomode *m;
  1212.     int i, found = 0;
  1213.  
  1214.     for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  1215.         m = (struct fb_videomode *)&hdmi_mode[i].mode;
  1216.         if (fb_mode_is_equal(m, mode)) {
  1217.             found = 1;
  1218.             break;
  1219.         }
  1220.     }
  1221.  
  1222.     if (found) {
  1223.         list_for_each(pos, head) {
  1224.             modelist = list_entry(pos,
  1225.                           struct display_modelist, list);
  1226.             m = &modelist->mode;
  1227.             if (fb_mode_is_equal(m, mode))
  1228.                 return 0;
  1229.             else if (hdmi_videomode_compare(m, mode) == -1)
  1230.                 break;
  1231.         }
  1232.  
  1233.         modelist_new = kmalloc(sizeof(*modelist_new), GFP_KERNEL);
  1234.         if (!modelist_new)
  1235.             return -ENOMEM;
  1236.         memset(modelist_new, 0, sizeof(struct display_modelist));
  1237.         modelist_new->mode = hdmi_mode[i].mode;
  1238.         modelist_new->vic = hdmi_mode[i].vic;
  1239.         list_add_tail(&modelist_new->list, pos);
  1240.     }
  1241.  
  1242.     return 0;
  1243. }
  1244.  
  1245. /**
  1246.  * hdmi_sort_modelist: sort modelist of edid
  1247.  * @edid: edid to be sort
  1248.  */
  1249. static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature)
  1250. {
  1251.     struct list_head *pos, *pos_new;
  1252.     struct list_head head_new, *head = &edid->modelist;
  1253.     struct display_modelist *modelist, *modelist_new, *modelist_n;
  1254.     struct fb_videomode *m, *m_new;
  1255.     int i, compare, vic;
  1256.  
  1257.     INIT_LIST_HEAD(&head_new);
  1258.     list_for_each(pos, head) {
  1259.         modelist = list_entry(pos, struct display_modelist, list);
  1260.         /*pr_info("%s vic %d\n", __function__, modelist->vic);*/
  1261.         for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  1262.             if ((modelist->vic & HDMI_VIDEO_DMT) || (modelist->vic & HDMI_VIDEO_DISCRETE_VR)) {
  1263.                 if (feature & (SUPPORT_VESA_DMT | SUPPORT_RK_DISCRETE_VR))
  1264.                     vic = modelist->vic;
  1265.                 else
  1266.                     continue;
  1267.             } else {
  1268.                 vic = modelist->vic & HDMI_VIC_MASK;
  1269.             }
  1270.             if (vic == hdmi_mode[i].vic ||
  1271.                 vic == hdmi_mode[i].vic_2nd) {
  1272.                 if ((feature & SUPPORT_4K) == 0 &&
  1273.                     hdmi_mode[i].mode.xres >= 3840)
  1274.                     continue;
  1275.                 if ((feature & SUPPORT_4K_4096) == 0 &&
  1276.                     hdmi_mode[i].mode.xres == 4096)
  1277.                     continue;
  1278.                 if ((feature & SUPPORT_TMDS_600M) == 0 &&
  1279.                     !(modelist->vic & HDMI_VIDEO_YUV420) &&
  1280.                     hdmi_mode[i].mode.pixclock > 340000000)
  1281.                     continue;
  1282.                 if ((modelist->vic & HDMI_VIDEO_YUV420) &&
  1283.                     (feature & SUPPORT_YUV420) == 0)
  1284.                     continue;
  1285.                 if ((feature & SUPPORT_1080I) == 0 &&
  1286.                     hdmi_mode[i].mode.xres == 1920 &&
  1287.                     (hdmi_mode[i].mode.vmode &
  1288.                      FB_VMODE_INTERLACED))
  1289.                     continue;
  1290.                 if ((feature & SUPPORT_480I_576I) == 0 &&
  1291.                     hdmi_mode[i].mode.xres == 720 &&
  1292.                     hdmi_mode[i].mode.vmode &
  1293.                      FB_VMODE_INTERLACED)
  1294.                     continue;
  1295.                 modelist->mode = hdmi_mode[i].mode;
  1296.                 if (modelist->vic & HDMI_VIDEO_YUV420)
  1297.                     modelist->mode.flag = 1;
  1298.  
  1299.                 compare = 1;
  1300.                 m = (struct fb_videomode *)&modelist->mode;
  1301.                 list_for_each(pos_new, &head_new) {
  1302.                     modelist_new =
  1303.                     list_entry(pos_new,
  1304.                            struct display_modelist,
  1305.                            list);
  1306.                     m_new = &modelist_new->mode;
  1307.                     compare =
  1308.                     hdmi_videomode_compare(m, m_new);
  1309.                     if (compare != -1)
  1310.                         break;
  1311.                 }
  1312.                 if (compare != 0) {
  1313.                     modelist_n =
  1314.                         kmalloc(sizeof(*modelist_n),
  1315.                             GFP_KERNEL);
  1316.                     if (!modelist_n)
  1317.                         return;
  1318.                     *modelist_n = *modelist;
  1319.                     list_add_tail(&modelist_n->list,
  1320.                               pos_new);
  1321.                 }
  1322.                 break;
  1323.             }
  1324.         }
  1325.     }
  1326.     fb_destroy_modelist(head);
  1327.     if (head_new.next == &head_new) {
  1328.         pr_info("There is no available video mode in EDID.\n");
  1329.         INIT_LIST_HEAD(&edid->modelist);
  1330.     } else {
  1331.         edid->modelist = head_new;
  1332.         edid->modelist.prev->next = &edid->modelist;
  1333.         edid->modelist.next->prev = &edid->modelist;
  1334.     }
  1335. }
  1336.  
  1337. static int edid_select_prop_value(struct hdmi *hdmi)
  1338. {
  1339.     struct edid_prop_value *prop_value = NULL;
  1340.     int nstates = 0;
  1341.     int i, vid, pid, sn, xres, yres, reboot = 0;
  1342.  
  1343.     prop_value = hdmi->pvalue;
  1344.     nstates = hdmi->nstates;
  1345.  
  1346.     if (!prop_value) {
  1347.         pr_info("%s:pvalue is NULL\n", __func__);
  1348.         return -1;
  1349.     }
  1350.  
  1351.     vid = hdmi->edid.value.vid;
  1352.     pid = hdmi->edid.value.pid;
  1353.     sn = hdmi->edid.value.sn;
  1354.     xres = hdmi->edid.value.xres;
  1355.     yres = hdmi->edid.value.yres;
  1356.  
  1357.     for (i = 0; i < nstates; i++) {
  1358.         if ((prop_value[i].vid == vid) &&
  1359.             (prop_value[i].pid == pid) &&
  1360.             (prop_value[i].sn == sn) &&
  1361.             (prop_value[i].xres == xres) &&
  1362.             (prop_value[i].yres == yres)) {
  1363.             hdmi->edid.value = prop_value[i];
  1364.             hdmi->prop.value = prop_value[i];
  1365.             if ((hdmi->prop.valid) &&
  1366.                 ((hdmi->prop.last_vid != vid) ||
  1367.                 (hdmi->prop.last_pid != pid) ||
  1368.                 (hdmi->prop.last_sn != sn) ||
  1369.                 (hdmi->prop.last_xres != xres) ||
  1370.                 (hdmi->prop.last_yres != yres))) {
  1371.                 reboot = 1;
  1372.             } else {
  1373.                 reboot = 0;
  1374.             }
  1375.  
  1376.             hdmi->prop.last_vid = vid;
  1377.             hdmi->prop.last_pid = pid;
  1378.             hdmi->prop.last_sn = sn;
  1379.             hdmi->prop.last_xres = xres;
  1380.             hdmi->prop.last_yres = yres;
  1381.             hdmi->prop.valid = 1;
  1382.             pr_info("%s:i=%d reboot=%d,valid=%d\n",
  1383.                 __func__, i, reboot, hdmi->prop.valid);
  1384.  
  1385.             break;
  1386.         }
  1387.     }
  1388.  
  1389.     if (reboot) {
  1390.         dev_info(hdmi->dev, "%s:kernel_restart\n", __func__);
  1391.         kernel_restart(NULL);
  1392.     }
  1393.  
  1394.     return 0;
  1395. }
  1396.  
  1397. /**
  1398.  * hdmi_ouputmode_select - select hdmi transmitter output mode: hdmi or dvi?
  1399.  * @hdmi: handle of hdmi
  1400.  * @edid_ok: get EDID data success or not, HDMI_ERROR_SUCCESS means success.
  1401.  */
  1402. int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
  1403. {
  1404.     struct list_head *head = &hdmi->edid.modelist;
  1405.     struct fb_monspecs *specs = hdmi->edid.specs;
  1406.     struct fb_videomode *modedb = NULL, *mode = NULL;
  1407.     int i, pixclock, feature = hdmi->property->feature;
  1408.  
  1409.     if (edid_ok != HDMI_ERROR_SUCCESS) {
  1410.         dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!");
  1411.         hdmi->edid.status = -1;
  1412.         hdmi->edid.sink_hdmi = 1;
  1413.         hdmi->edid.baseaudio_support = 1;
  1414.         hdmi->edid.ycbcr444 = 0;
  1415.         hdmi->edid.ycbcr422 = 0;
  1416.     }
  1417.  
  1418.     if (hdmi->edid_auto_support)
  1419.         edid_select_prop_value(hdmi);
  1420.  
  1421.     if (head->next == head) {
  1422.         dev_info(hdmi->dev,
  1423.              "warning: no CEA video mode parsed from EDID !!!!\n");
  1424.         /* If EDID get error, list all system supported mode.
  1425.          * If output mode is set to DVI and EDID is ok, check
  1426.          * the output timing.
  1427.          */
  1428.         if (hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) {
  1429.             /* Get max resolution timing */
  1430.             modedb = &specs->modedb[0];
  1431.             for (i = 0; i < specs->modedb_len; i++) {
  1432.                 if (specs->modedb[i].xres > modedb->xres)
  1433.                     modedb = &specs->modedb[i];
  1434.                 else if (specs->modedb[i].xres ==
  1435.                      modedb->xres &&
  1436.                      specs->modedb[i].yres > modedb->yres)
  1437.                     modedb = &specs->modedb[i];
  1438.             }
  1439.             /* For some monitor, the max pixclock read from EDID
  1440.              * is smaller than the clock of max resolution mode
  1441.              * supported. We fix it.
  1442.              */
  1443.             pixclock = PICOS2KHZ(modedb->pixclock);
  1444.             pixclock /= 250;
  1445.             pixclock *= 250;
  1446.             pixclock *= 1000;
  1447.             if (pixclock == 148250000)
  1448.                 pixclock = 148500000;
  1449.             if (pixclock > specs->dclkmax)
  1450.                 specs->dclkmax = pixclock;
  1451.         }
  1452.  
  1453.         for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  1454.             mode = (struct fb_videomode *)&hdmi_mode[i].mode;
  1455.             if (modedb) {
  1456.                 if ((mode->pixclock < specs->dclkmin) ||
  1457.                     (mode->pixclock > specs->dclkmax) ||
  1458.                     (mode->refresh < specs->vfmin) ||
  1459.                     (mode->refresh > specs->vfmax) ||
  1460.                     (mode->xres > modedb->xres) ||
  1461.                     (mode->yres > modedb->yres))
  1462.                     continue;
  1463.             } else {
  1464.                 /* If there is no valid information in EDID,
  1465.                  * just list common hdmi foramt.
  1466.                  */
  1467.                 if (mode->xres > 3840 ||
  1468.                     mode->refresh < 50 ||
  1469.                     (mode->vmode & FB_VMODE_INTERLACED) ||
  1470.                     hdmi_mode[i].vic & HDMI_VIDEO_DMT ||
  1471.                     hdmi_mode[i].vic & HDMI_VIDEO_DISCRETE_VR)
  1472.                     continue;
  1473.             }
  1474.             if ((feature & SUPPORT_TMDS_600M) == 0 &&
  1475.                 mode->pixclock > 340000000)
  1476.                 continue;
  1477.             if ((feature & SUPPORT_4K) == 0 &&
  1478.                 mode->xres >= 3840)
  1479.                 continue;
  1480.             if ((feature & SUPPORT_4K_4096) == 0 &&
  1481.                 mode->xres == 4096)
  1482.                 continue;
  1483.             if ((feature & SUPPORT_1080I) == 0 &&
  1484.                 mode->xres == 1920 &&
  1485.                 (mode->vmode & FB_VMODE_INTERLACED))
  1486.                 continue;
  1487.             if ((feature & SUPPORT_480I_576I) == 0 &&
  1488.                 mode->xres == 720 &&
  1489.                 (mode->vmode & FB_VMODE_INTERLACED))
  1490.                 continue;
  1491.             hdmi_add_videomode(mode, head);
  1492.         }
  1493.     } else {
  1494.         /* There are some video mode is not defined in EDID extend
  1495.          * block, so we need to check first block data.
  1496.          */
  1497.         if (specs && specs->modedb_len) {
  1498.             for (i = 0; i < specs->modedb_len; i++) {
  1499.                 modedb = &specs->modedb[i];
  1500.                 pixclock = hdmi_videomode_to_vic(modedb);
  1501.                 if (pixclock)
  1502.                     hdmi_add_vic(pixclock, head);
  1503.             }
  1504.         }
  1505.         hdmi_sort_modelist(&hdmi->edid, hdmi->property->feature);
  1506.     }
  1507.  
  1508.     return HDMI_ERROR_SUCCESS;
  1509. }
  1510.  
  1511. /**
  1512.  * hdmi_videomode_to_vic: transverse video mode to vic
  1513.  * @vmode: videomode to transverse
  1514.  *
  1515.  */
  1516. int hdmi_videomode_to_vic(struct fb_videomode *vmode)
  1517. {
  1518.     struct fb_videomode *mode;
  1519.     unsigned int vic = 0;
  1520.     int i = 0;
  1521.  
  1522.     for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  1523.         mode = (struct fb_videomode *)&hdmi_mode[i].mode;
  1524.         if (vmode->vmode == mode->vmode &&
  1525.             vmode->refresh == mode->refresh &&
  1526.             vmode->xres == mode->xres &&
  1527.             vmode->yres == mode->yres &&
  1528.             vmode->left_margin == mode->left_margin &&
  1529.             vmode->right_margin == mode->right_margin &&
  1530.             vmode->upper_margin == mode->upper_margin &&
  1531.             vmode->lower_margin == mode->lower_margin &&
  1532.             vmode->hsync_len == mode->hsync_len &&
  1533.             vmode->vsync_len == mode->vsync_len) {
  1534.             vic = hdmi_mode[i].vic;
  1535.             break;
  1536.         }
  1537.     }
  1538.     return vic;
  1539. }
  1540.  
  1541. /**
  1542.  * hdmi_vic2timing: transverse vic mode to video timing
  1543.  * @vmode: vic to transverse
  1544.  *
  1545.  */
  1546. const struct hdmi_video_timing *hdmi_vic2timing(int vic)
  1547. {
  1548.     int i;
  1549.  
  1550.     if (vic == 0)
  1551.         return NULL;
  1552.  
  1553.     for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  1554.         if (hdmi_mode[i].vic == vic || hdmi_mode[i].vic_2nd == vic)
  1555.             return &hdmi_mode[i];
  1556.     }
  1557.     return NULL;
  1558. }
  1559.  
  1560. /**
  1561.  * hdmi_vic_to_videomode: transverse vic mode to video mode
  1562.  * @vmode: vic to transverse
  1563.  *
  1564.  */
  1565. const struct fb_videomode *hdmi_vic_to_videomode(int vic)
  1566. {
  1567.     int i, vid;
  1568.  
  1569.     if (vic == 0)
  1570.         return NULL;
  1571.     else if ((vic & HDMI_VIDEO_DMT) || (vic & HDMI_VIDEO_DISCRETE_VR))
  1572.         vid = vic;
  1573.     else
  1574.         vid = vic & HDMI_VIC_MASK;
  1575.     for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  1576.         if (hdmi_mode[i].vic == vid ||
  1577.             hdmi_mode[i].vic_2nd == vid)
  1578.             return &hdmi_mode[i].mode;
  1579.     }
  1580.     return NULL;
  1581. }
  1582.  
  1583. /**
  1584.  * hdmi_init_modelist: initial hdmi mode list
  1585.  * @hdmi:
  1586.  *
  1587.  * NOTES:
  1588.  *
  1589.  */
  1590. void hdmi_init_modelist(struct hdmi *hdmi)
  1591. {
  1592.     int i, feature;
  1593.     struct list_head *head = &hdmi->edid.modelist;
  1594.  
  1595.     feature = hdmi->property->feature;
  1596.     INIT_LIST_HEAD(&hdmi->edid.modelist);
  1597.     for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
  1598.         if ((hdmi_mode[i].vic & HDMI_VIDEO_DMT) || (hdmi_mode[i].vic & HDMI_VIDEO_DISCRETE_VR))
  1599.             continue;
  1600.         if ((feature & SUPPORT_TMDS_600M) == 0 &&
  1601.             hdmi_mode[i].mode.pixclock > 340000000)
  1602.             continue;
  1603.         if ((feature & SUPPORT_4K) == 0 &&
  1604.             hdmi_mode[i].mode.xres >= 3840)
  1605.             continue;
  1606.         if ((feature & SUPPORT_4K_4096) == 0 &&
  1607.             hdmi_mode[i].mode.xres == 4096)
  1608.             continue;
  1609.         if ((feature & SUPPORT_1080I) == 0 &&
  1610.             hdmi_mode[i].mode.xres == 1920 &&
  1611.             (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
  1612.             continue;
  1613.         if ((feature & SUPPORT_480I_576I) == 0 &&
  1614.             hdmi_mode[i].mode.xres == 720 &&
  1615.             (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
  1616.             continue;
  1617.         hdmi_add_videomode(&hdmi_mode[i].mode, head);
  1618.     }
  1619. }
Add Comment
Please, Sign In to add comment