diff --git a/SOFTWARE/A64-TERES/blobs/sun50i-a64-teres.dts b/SOFTWARE/A64-TERES/blobs/sun50i-a64-teres.dts index 21dcc718..234b413e 100644 --- a/SOFTWARE/A64-TERES/blobs/sun50i-a64-teres.dts +++ b/SOFTWARE/A64-TERES/blobs/sun50i-a64-teres.dts @@ -2155,14 +2155,17 @@ status = "okay"; device_type = "disp"; disp_init_enable = <0x1>; - disp_mode = <0x0>; + disp_mode = <0x3>; screen0_output_type = <0x1>; screen0_output_mode = <0x4>; screen1_output_type = <0x3>; screen1_output_mode = <0xa>; + fb_mode = <0x3>; + fb0_mode = <0x3>; fb0_format = <0x0>; fb0_width = <0x0>; fb0_height = <0x0>; + fb1_mode = <0x3>; fb1_format = <0x0>; fb1_width = <0x0>; fb1_height = <0x0>; diff --git a/SOFTWARE/A64-TERES/linux-a64/Makefile b/SOFTWARE/A64-TERES/linux-a64/Makefile index f4c4de45..bf95acfb 100644 --- a/SOFTWARE/A64-TERES/linux-a64/Makefile +++ b/SOFTWARE/A64-TERES/linux-a64/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 10 SUBLEVEL = 104 -EXTRAVERSION = +EXTRAVERSION = -teres NAME = TOSSUG Baby Fish # *DOCUMENTATION* diff --git a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/disp/de/disp_display.c b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/disp/de/disp_display.c index 27d64b86..82342adf 100755 --- a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/disp/de/disp_display.c +++ b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/disp/de/disp_display.c @@ -743,6 +743,14 @@ s32 bsp_disp_get_screen_width_from_output_type(u32 disp, u32 output_type, u32 ou width = 3840; height = 2160; break; + case DISP_TV_MOD_800_480P: + width = 800; + height = 480; + break; + case DISP_TV_MOD_1024_600P: + width = 1024; + height = 600; + break; } } /* FIXME: add other output device res */ diff --git a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/Makefile b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/Makefile index 3ee5218d..a419a631 100755 --- a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/Makefile +++ b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_HDMI_DISP2_SUNXI) += hdmi.o obj-m += hdmi_cec.o hdmi-y := drv_hdmi.o hdmi_core.o hdmi_edid.o -hdmi-$(CONFIG_ARCH_SUN50IW1P1) += libhdmi_sun50iw1.o +hdmi-$(CONFIG_ARCH_SUN50IW1P1) += hdmi_bsp_sun50iw1p1.o hdmi-$(CONFIG_ARCH_SUN8IW11) += libhdmi_sun8iw11 $(obj)/libhdmi_sun50iw1.o: diff --git a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c index cf0c1c7e..5d77e6f5 100755 --- a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c +++ b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c @@ -304,6 +304,8 @@ static struct disp_hdmi_mode hdmi_mode_tbl[] = { {DISP_TV_MOD_720P_60HZ_3D_FP, HDMI720P_60_3D_FP, }, {DISP_TV_MOD_3840_2160P_30HZ, HDMI3840_2160P_30, }, {DISP_TV_MOD_3840_2160P_25HZ, HDMI3840_2160P_25, }, + {DISP_TV_MOD_800_480P, HDMI800_480P, }, + {DISP_TV_MOD_1024_600P, HDMI1024_600P, }, }; static u32 hdmi_get_vic(u32 mode) @@ -1041,6 +1043,12 @@ static ssize_t hdmi_hdcp_enable_store(struct device *dev, static DEVICE_ATTR(hdcp_enable, S_IRUGO|S_IWUSR|S_IWGRP,hdmi_hdcp_enable_show, hdmi_hdcp_enable_store); +ssize_t hdmi_modeline_show(struct device *dev,struct device_attribute *attr, char *buf); +ssize_t hdmi_modeline_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static DEVICE_ATTR(modeline, S_IRUGO|S_IWUSR|S_IWGRP, hdmi_modeline_show, hdmi_modeline_store); + static int __init hdmi_probe(struct platform_device *pdev) { __inf("hdmi_probe call\n"); @@ -1121,6 +1129,7 @@ static struct attribute *hdmi_attributes[] = &dev_attr_hpd_mask.attr, &dev_attr_edid.attr, &dev_attr_hdcp_enable.attr, + &dev_attr_modeline.attr, NULL }; diff --git a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_bsp.h b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_bsp.h index 0b45f420..d2cade0f 100755 --- a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_bsp.h +++ b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_bsp.h @@ -36,6 +36,7 @@ struct video_para unsigned char is_hdmi; unsigned char is_yuv; unsigned char is_hcts; + unsigned int para[19]; }; enum audio_type @@ -64,6 +65,7 @@ struct audio_para unsigned int sample_bit; unsigned int ch_num; unsigned int vic; + unsigned int para[19]; }; int bsp_hdmi_set_func(hdmi_bsp_func *func); diff --git a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.c b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.c index 93783cdf..a43273a6 100755 --- a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.c +++ b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.c @@ -30,7 +30,7 @@ EXPORT_SYMBOL(hdmi_delay_ms); struct disp_video_timings video_timing[] = { - //VIC PCLK AVI_PR X Y HT HBP HFP HST VT VBP VFP VST h_pol v_pol int vac trd + //VIC PCLK AVI_PR X Y HT HBP HFP HST VT VBP VFP VST h_pl v_pl int vac trd {HDMI1440_480I, 0,13500000, 1, 720, 480, 858, 57, 19, 62, 525, 15, 4, 3, 0, 0, 1, 0, 0}, {HDMI1440_576I, 0,13500000, 1, 720, 576, 864, 69, 12, 63, 625, 19, 2, 3, 0, 0, 1, 0, 0}, {HDMI480P, 0,27000000, 0, 720, 480, 858, 60, 16, 62, 525, 30, 9, 6, 0, 0, 0, 0, 0}, @@ -49,9 +49,103 @@ struct disp_video_timings video_timing[] = {HDMI720P_60_3D_FP, 0,148500000, 0, 1280, 1440, 1650, 220, 110, 40, 750, 20, 5, 5, 1, 1, 0, 30, 1}, {HDMI3840_2160P_30, 0,297000000, 0, 3840, 2160, 4400, 296, 176, 88, 2250, 72, 8, 10, 1, 1, 0, 0, 0}, {HDMI3840_2160P_25, 0,297000000, 0, 3840, 2160, 5280, 296, 1056, 88, 2250, 72, 8, 10, 1, 1, 0, 0, 0}, + {HDMI800_480P, 0,74250000, 0, 800, 480, 928, 40, 40, 48, 525, 29, 13, 3, 0, 0, 0, 0, 0}, + {HDMI1024_600P, 0,74250000, 0, 1024, 600, 1152, 40, 40, 48, 645, 29, 13, 3, 0, 0, 0, 0, 0}, {HDMI_EDID,}, }; +ssize_t hdmi_modeline_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return -ENODEV; +} + +ssize_t hdmi_modeline_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int index = -1; + int pixel_clk, ver = 0, inter = 0; + int hdisp, hstart, hend, htotal; + int vdisp, vstart, vend, vtotal; + + int ret = sscanf(buf, "%d %d %d %d %d %d %d %d %d %d %d %d", + &index, + &pixel_clk, &hdisp, &hstart, &hend, &htotal, + &vdisp, &vstart, &vend, &vtotal, + &ver, &inter); + if (ret < 10) { + return -EINVAL; + } + + int modeline = hdmi_core_get_video_info(index); + if (modeline < 0) { + return -ENODEV; + } + + struct disp_video_timings *timing = &video_timing[modeline]; + + timing->pixel_clk = pixel_clk * 1000000; + timing->x_res = hdisp; + timing->y_res = vdisp; + timing->hor_total_time = htotal; + timing->hor_back_porch = htotal - hend; + timing->hor_front_porch = hstart - hdisp; + timing->hor_sync_time = hend - hstart; + timing->ver_total_time = vtotal; + timing->ver_back_porch = vtotal - vend; + timing->ver_front_porch = vstart - vdisp; + timing->ver_sync_time = vend - vstart; + timing->hor_sync_polarity = timing->ver_sync_polarity = ver; + timing->b_interlace = inter; + return count; +} + +static int hdmi_core_set_para_param(int vic, unsigned int *para) +{ + int i; + int index = hdmi_core_get_video_info(vic); + if (index < 0) { + printk(KERN_ERR "HDMI failed to find video_timing for VIC:%d\n", vic); + return -ENODEV; + } + + struct disp_video_timings *timing = &video_timing[index]; + + para[0] = timing->vic; + if (timing->pixel_clk <= 27000000) + para[1] = 11; + else if (timing->pixel_clk <= 74250000) + para[1] = 4; + else if (timing->pixel_clk <= 148500000) + para[1] = 2; + else + para[1] = 1; + para[2] = timing->tv_mode; + para[3] = (timing->hor_sync_polarity ? 96 : 0) | (timing->b_interlace ? 1 : 0); + para[4] = timing->x_res >> 8; + para[5] = timing->ver_sync_time; + para[6] = timing->y_res >> 8; + para[7] = (timing->hor_total_time - timing->x_res) >> 8; + para[8] = timing->ver_front_porch; + para[9] = timing->hor_front_porch >> 8; + para[10] = timing->hor_sync_time >> 8; + para[11] = timing->x_res & 0xFF; + para[12] = (timing->hor_total_time - timing->x_res) & 0xFF; + para[13] = timing->hor_front_porch & 0xFF; + para[14] = timing->hor_sync_time & 0xFF; + para[15] = timing->y_res & 0xFF; + para[16] = (timing->ver_total_time - timing->y_res) & 0xFF; + para[17] = 1; + para[18] = 1; + + printk(KERN_INFO "HDMI set ptbl: "); + for(i = 0; i < 19; ++i) { + printk("%d ", para[i]); + } + printk("\n"); + return 0; +} + static void hdmi_para_reset(void) { hdmi_state = HDMI_State_Idle; @@ -391,6 +485,7 @@ static s32 audio_config_internal(void) return 0; } + hdmi_core_set_para_param(glb_audio_para.vic, glb_audio_para.para); if (bsp_hdmi_audio(&glb_audio_para)) { __wrn("set hdmi audio error!\n"); @@ -459,6 +554,7 @@ s32 hdmi_core_set_video_enable(bool enable) video_config(glb_video_para.vic); __inf("hdmi_core_set_video_enable, vic:%d,is_hdmi:%d,is_yuv:%d,is_hcts:%d\n", glb_video_para.vic, glb_video_para.is_hdmi,glb_video_para.is_yuv, glb_video_para.is_hcts); + hdmi_core_set_para_param(glb_video_para.vic, glb_video_para.para); if (bsp_hdmi_video(&glb_video_para)) { __wrn("set hdmi video error!\n"); diff --git a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.h b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.h index 8d89ef13..6e562f40 100755 --- a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.h +++ b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_core.h @@ -18,6 +18,8 @@ #define HDMI1080P_24 32 #define HDMI1080P_25 33 #define HDMI1080P_30 34 +#define HDMI800_480P 35 +#define HDMI1024_600P 36 #define HDMI1080P_24_3D_FP (HDMI1080P_24 +0x80) #define HDMI720P_50_3D_FP (HDMI720P_50 +0x80) #define HDMI720P_60_3D_FP (HDMI720P_60 +0x80) diff --git a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_edid.c b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_edid.c index 3941f0f4..3b2a104a 100755 --- a/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_edid.c +++ b/SOFTWARE/A64-TERES/linux-a64/drivers/video/sunxi/disp2/hdmi/hdmi_edid.c @@ -141,6 +141,12 @@ static s32 edid_parse_dtd_block(u8 *pbuf) if ((sizex== 1280) && (sizey == 720)) { Device_Support_VIC[HDMI720P_60] = 1; } + if ((sizex== 800) && (sizey == 480)) { + Device_Support_VIC[HDMI800_480P] = 1; + } + if ((sizex== 1024) && (sizey == 600)) { + Device_Support_VIC[HDMI1024_600P] = 1; + } if ((sizex== 1920) && (sizey == 540)) { Device_Support_VIC[HDMI1080I_60] = 1; } @@ -155,6 +161,12 @@ static s32 edid_parse_dtd_block(u8 *pbuf) if ((sizex== 720) && (sizey == 576)) { Device_Support_VIC[HDMI576P] = 1; } + if ((sizex== 800) && (sizey == 480)) { + Device_Support_VIC[HDMI800_480P] = 1; + } + if ((sizex== 1024) && (sizey == 600)) { + Device_Support_VIC[HDMI1024_600P] = 1; + } if ((sizex== 1280) && (sizey == 720)) { Device_Support_VIC[HDMI720P_50] = 1; } diff --git a/SOFTWARE/A64-TERES/linux-a64/include/video/sunxi_display2.h b/SOFTWARE/A64-TERES/linux-a64/include/video/sunxi_display2.h index 55acac3f..9557ad26 100755 --- a/SOFTWARE/A64-TERES/linux-a64/include/video/sunxi_display2.h +++ b/SOFTWARE/A64-TERES/linux-a64/include/video/sunxi_display2.h @@ -153,7 +153,9 @@ enum disp_tv_mode DISP_TV_MOD_3840_2160P_30HZ = 0x1c, DISP_TV_MOD_3840_2160P_25HZ = 0x1d, DISP_TV_MOD_3840_2160P_24HZ = 0x1e, - DISP_TV_MODE_NUM = 0x1f, + DISP_TV_MOD_800_480P = 0x1f, + DISP_TV_MOD_1024_600P = 0x20, + DISP_TV_MODE_NUM = 0x21, };