From 75a95d62806170f00f314b520bd18d5bf1163877 Mon Sep 17 00:00:00 2001 From: Joy Cho Date: Wed, 9 Jan 2019 15:50:35 +0900 Subject: [PATCH] ODROID-N2: hdmitx: add hdmi phy custombuilt mode Change-Id: I2ee9c9eccda7d54e6a801ed6b90039deb3c3fc75 --- .../vout/hdmitx/hdmi_common/hdmi_parameters.c | 204 ++++++++++++++++++ .../vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c | 1 + .../vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c | 7 + .../vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c | 11 + .../vout/hdmitx/hdmi_tx_20/hw/enc_cfg_hw.c | 63 +++++- .../vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c | 19 ++ .../media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c | 16 ++ .../media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c | 23 ++ .../amlogic/media/vout/hdmi_tx/hdmi_common.h | 1 + .../media/vout/hdmi_tx/hdmi_tx_module.h | 1 + 10 files changed, 335 insertions(+), 11 deletions(-) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c b/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c index 4d85b5b69682..83a43398d554 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c @@ -17,8 +17,33 @@ #include #include +#include #include +struct modeline_table { + /* resolutions */ + unsigned int horpixels; + unsigned int verpixels; + /* clock and frequency */ + unsigned int pixel_clock; + unsigned int hor_freq; + unsigned int ver_freq; + /* htimings */ + unsigned int hdisp; + unsigned int hsyncstart; + unsigned int hsyncend; + unsigned int htotal; + /* vtiminigs */ + unsigned int vdisp; + unsigned int vsyncstart; + unsigned int vsyncend; + unsigned int vtotal; + /* polarity and scan mode */ + unsigned int hsync_polarity; /* 1:+hsync, 0:-hsync */ + unsigned int vsync_polarity; /* 1:+vsync, 0:-vsync */ + unsigned int progress_mode; /* 1:progress, 0:interlaced */ +}; + static struct hdmi_format_para fmt_para_1920x1080p60_16x9 = { .vic = HDMI_1920x1080p60_16x9, .name = "1920x1080p60hz", @@ -2198,6 +2223,27 @@ static struct hdmi_format_para fmt_para_480x800p60_4x3 = { }, }; +static struct hdmi_format_para fmt_para_custombuilt = { + .vic = HDMI_CUSTOMBUILT, + .name = "custombuilt", + .sname = "custombuilt", + .pixel_repetition_factor = 0, + .scrambler_en = 0, + .tmds_clk_div40 = 0, + .timing = { + .v_sync_ln = 1, + }, + .hdmitx_vinfo = { + .name = "custombuilt", + .mode = VMODE_HDMI, + .aspect_ratio_num = 16, + .aspect_ratio_den = 9, + .sync_duration_den = 1, + .viu_color_fmt = COLOR_FMT_YUV444, + .viu_mux = VIU_MUX_ENCP, + }, +}; + static struct hdmi_format_para fmt_para_non_hdmi_fmt = { .vic = HDMI_Unknown, .name = "invalid", @@ -2298,6 +2344,7 @@ static struct hdmi_format_para *all_fmt_paras[] = { &fmt_para_640x480p60_4x3, &fmt_para_480x320p60_4x3, &fmt_para_480x800p60_4x3, + &fmt_para_custombuilt, &fmt_para_null_hdmi_fmt, &fmt_para_non_hdmi_fmt, NULL, @@ -2314,6 +2361,163 @@ struct hdmi_format_para *hdmi_get_fmt_paras(enum hdmi_vic vic) return &fmt_para_non_hdmi_fmt; } +/* +void debug_modeline(struct modeline_table tbl) +{ + pr_info("modeline - horpixels %d\n", tbl.horpixels); + pr_info("modeline - verpixels %d\n", tbl.verpixels); + pr_info("modeline - pixel_clock %d\n", tbl.pixel_clock); + pr_info("modeline - hor_freq %d\n", tbl.hor_freq); + pr_info("modeline - ver_freq %d\n", tbl.ver_freq); + pr_info("modeline - hdisp %d\n", tbl.hdisp); + pr_info("modeline - hsyncstart %d\n", tbl.hsyncstart); + pr_info("modeline - hsyncend %d\n", tbl.hsyncend); + pr_info("modeline - htotal %d\n", tbl.htotal); + pr_info("modeline - vdisp %d\n", tbl.vdisp); + pr_info("modeline - vsyncstart %d\n", tbl.vsyncstart); + pr_info("modeline - vsyncend %d\n", tbl.vsyncend); + pr_info("modeline - vtotal %d\n", tbl.vtotal); + pr_info("modeline - hsync_polarity %d\n", tbl.hsync_polarity); + pr_info("modeline - vsync_polarity %d\n", tbl.vsync_polarity); + pr_info("modeline - progress_mode %d\n", tbl.progress_mode); +} +*/ + +void debug_hdmi_fmt_param(struct hdmi_format_para param) +{ + /* timing */ + pr_info("fmt_para.timing\n"); + pr_info(" - pixel_freq %d, frac_freq %d\n", + param.timing.pixel_freq, param.timing.frac_freq); + pr_info(" - h_freq %d, v_freq %d\n", + param.timing.h_freq, param.timing.v_freq); + pr_info(" - hsync_polarity %d, vsync_polarity %d\n", + param.timing.hsync_polarity, + param.timing.vsync_polarity); + pr_info(" - h_active %d, h_total %d\n", + param.timing.h_active, param.timing.h_total); + pr_info(" - h_blank %d, h_front %d, h_sync %d, h_back %d\n", + param.timing.h_blank, param.timing.h_front, + param.timing.h_sync, param.timing.h_back); + pr_info(" - v_active %d, v_total %d\n", + param.timing.v_active, param.timing.v_total); + pr_info(" - v_blank %d, v_front %d, v_sync %d, v_back %d\n", + param.timing.v_blank, param.timing.v_front, + param.timing.v_sync, param.timing.v_back); + pr_info(" - v_sync_ln %d\n", param.timing.v_sync_ln); + + /* hdmitx_vinfo */ + pr_info("fmt_para.hdmitx_vinfo\n"); + pr_info(" - name %s, mode %d\n", + param.hdmitx_vinfo.name, param.hdmitx_vinfo.mode); + pr_info(" - width %d, height %d, field_height %d\n", + param.hdmitx_vinfo.width, param.hdmitx_vinfo.height, + param.hdmitx_vinfo.field_height); + pr_info(" - aspect_ratio_num %d, aspect_ratio_den %d\n", + param.hdmitx_vinfo.aspect_ratio_num, + param.hdmitx_vinfo.aspect_ratio_den); + pr_info(" - video_clk %d\n", param.hdmitx_vinfo.video_clk); + pr_info(" - htotal %d, vtotal %d\n", + param.hdmitx_vinfo.htotal, param.hdmitx_vinfo.vtotal); + pr_info(" - viu_color_fmt %d, viu_mux %d\n", + param.hdmitx_vinfo.viu_color_fmt, + param.hdmitx_vinfo.viu_mux); +} + +/* + * assuming modeline information from command line is as following. + * setenv modeline + * "horpixels,verpixels,pixel_clock,hor_freq,ver_freq + * ,hdisp,hsyncstart,hsyncend,htotal,vdisp,vsyncstart,vsyncend,vtotal + * ,hsync_polarity,vsync_polarity,progress_mode" + */ +static int __init setup_modeline(char *s) +{ + struct hdmi_cea_timing *custom_timing; + struct modeline_table tbl; + unsigned int *buf; + char *item = NULL; + unsigned long temp = 0; + int ret; + int i = 0; + + /* 1. parsing modeline information from command line */ + buf = (unsigned int *)&(tbl.horpixels); + + while (s != NULL) { + item = strsep(&s, ","); + ret = kstrtoul(item, 0, &temp); + *(buf + i) = temp; + i++; + } + + /* check parameters */ + // debug_modeline(tbl); + + /* 2. build hdmi_format_para */ + fmt_para_custombuilt.progress_mode = tbl.progress_mode; + fmt_para_custombuilt.tmds_clk = tbl.pixel_clock; + + /* timing */ + fmt_para_custombuilt.timing.pixel_freq = tbl.pixel_clock; + fmt_para_custombuilt.timing.frac_freq = tbl.pixel_clock; + fmt_para_custombuilt.timing.h_freq = tbl.hor_freq; + fmt_para_custombuilt.timing.v_freq = (tbl.ver_freq * 1000); + fmt_para_custombuilt.timing.hsync_polarity = tbl.hsync_polarity; + fmt_para_custombuilt.timing.vsync_polarity = tbl.vsync_polarity; + /* h_active = hdisp */ + fmt_para_custombuilt.timing.h_active = tbl.hdisp; + /* h_total = htotal */ + fmt_para_custombuilt.timing.h_total = tbl.htotal; + /* h_blank = htotal - hdisp */ + fmt_para_custombuilt.timing.h_blank = tbl.htotal - tbl.hdisp; + /* h_front = hsyncstart - hdisp */ + fmt_para_custombuilt.timing.h_front = tbl.hsyncstart - tbl.hdisp; + /* h_sync = hsyncend - hsyncstart */ + fmt_para_custombuilt.timing.h_sync = tbl.hsyncend - tbl.hsyncstart; + /* h_back = (h_blank - (h_front + h_sync))*/ + fmt_para_custombuilt.timing.h_back + = fmt_para_custombuilt.timing.h_blank + - fmt_para_custombuilt.timing.h_front + - fmt_para_custombuilt.timing.h_sync; + /* v_active = vdisp */ + fmt_para_custombuilt.timing.v_active = tbl.vdisp; + /* v_total = vtotal */ + fmt_para_custombuilt.timing.v_total = tbl.vtotal; + /* v_blank = vtotal - vdisp */ + fmt_para_custombuilt.timing.v_blank = tbl.vtotal - tbl.vdisp; + /* v_front = vsyncstart - vdisp */ + fmt_para_custombuilt.timing.v_front = tbl.vsyncstart - tbl.vdisp; + /* v_sync = vsyncend - vsyncstart */ + fmt_para_custombuilt.timing.v_sync = tbl.vsyncend - tbl.vsyncstart; + /* v_back = (v_blank - (v_front + v_sync)) */ + fmt_para_custombuilt.timing.v_back + = fmt_para_custombuilt.timing.v_blank + - fmt_para_custombuilt.timing.v_front + - fmt_para_custombuilt.timing.v_sync; + fmt_para_custombuilt.timing.v_sync_ln = 1; + + /* hdmitx_vinfo */ + fmt_para_custombuilt.hdmitx_vinfo.width = tbl.hdisp; + fmt_para_custombuilt.hdmitx_vinfo.height = tbl.vdisp; + fmt_para_custombuilt.hdmitx_vinfo.field_height = tbl.vdisp; + fmt_para_custombuilt.hdmitx_vinfo.sync_duration_num = tbl.ver_freq; + fmt_para_custombuilt.hdmitx_vinfo.video_clk = (tbl.pixel_clock * 1000); + fmt_para_custombuilt.hdmitx_vinfo.htotal = tbl.htotal; + fmt_para_custombuilt.hdmitx_vinfo.vtotal = tbl.vtotal; + + /* check parameters */ + debug_hdmi_fmt_param(fmt_para_custombuilt); + + /* 3. copy custom-built timing information for backup */ + custom_timing = get_custom_timing(); + memcpy(custom_timing, &fmt_para_custombuilt.timing, + sizeof(fmt_para_custombuilt.timing)); + + return 0; +} +__setup("modeline=", setup_modeline); + struct hdmi_format_para *hdmi_match_dtd_paras(struct dtd *t) { int i; diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c index 4c58c3e1039d..8117bab3bdba 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c @@ -2206,6 +2206,7 @@ static struct dispmode_vic dispmode_vic_tab[] = { {"640x480p60hz", HDMI_640x480p60_4x3}, {"480x320p60hz", HDMI_480x320p60_4x3}, {"480x800p60hz", HDMI_480x800p60_4x3}, + {"custombuilt", HDMI_CUSTOMBUILT}, }; int hdmitx_edid_VIC_support(enum hdmi_vic vic) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index 9fb3b513f6a2..50f2ddd3fff6 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -108,6 +108,13 @@ struct extcon_dev *hdmitx_extcon_hdr; struct extcon_dev *hdmitx_extcon_rxsense; struct extcon_dev *hdmitx_extcon_hdcp; +static struct hdmi_cea_timing custom_timing; +struct hdmi_cea_timing *get_custom_timing(void) +{ + return &custom_timing; +} +EXPORT_SYMBOL(get_custom_timing); + static inline void hdmitx_notify_hpd(int hpd) { if (hpd) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c index d727082f6de7..ea6263fe7fa6 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c @@ -688,6 +688,17 @@ static struct hdmitx_vidpara hdmi_tx_video_params[] = { .ss = SS_SCAN_UNDER, .sc = SC_SCALE_HORIZ_VERT, }, + { + .VIC = HDMI_CUSTOMBUILT, + .color_prefer = COLORSPACE_RGB444, + .color_depth = COLORDEPTH_24B, + .bar_info = B_BAR_VERT_HORIZ, + .repeat_time = NO_REPEAT, + .aspect_ratio = ASPECT_RATIO_SAME_AS_SOURCE, + .cc = CC_ITU709, + .ss = SS_SCAN_UNDER, + .sc = SC_SCALE_HORIZ_VERT, + }, }; static struct hdmitx_vidpara *hdmi_get_video_param( diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/enc_cfg_hw.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/enc_cfg_hw.c index 38eab89a796c..ed2514a8d57d 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/enc_cfg_hw.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/enc_cfg_hw.c @@ -1423,6 +1423,38 @@ static struct vic_tvregs_set tvregsTab_3dfp[] = { {HDMI_1280x720p50_16x9, tvregs_3dfp_720p50}, }; +void build_custom_vic_tvregs(void) +{ + struct hdmi_cea_timing *custom_timing = get_custom_timing(); + + hd_write_reg(P_VENC_VDAC_SETTING, 0xff); + + hd_write_reg(P_ENCP_VIDEO_EN, 0); + hd_write_reg(P_ENCI_VIDEO_EN, 0); + + hd_write_reg(P_ENCP_VIDEO_MODE, 0x4040); + hd_write_reg(P_ENCP_VIDEO_MODE_ADV, 0x18); + + hd_write_reg(P_ENCP_VIDEO_MAX_PXCNT, (custom_timing->h_total - 1)); + hd_write_reg(P_ENCP_VIDEO_MAX_LNCNT, (custom_timing->v_total - 1)); + + hd_write_reg(P_ENCP_VIDEO_HAVON_BEGIN, custom_timing->h_back); + hd_write_reg(P_ENCP_VIDEO_HAVON_END, + ((custom_timing->h_back + custom_timing->h_active) - 1)); + hd_write_reg(P_ENCP_VIDEO_VAVON_BLINE, custom_timing->v_back); + hd_write_reg(P_ENCP_VIDEO_VAVON_ELINE, + ((custom_timing->v_back + custom_timing->v_active) - 1)); + + hd_write_reg(P_ENCP_VIDEO_HSO_BEGIN, 0); + hd_write_reg(P_ENCP_VIDEO_HSO_END, custom_timing->h_sync); + hd_write_reg(P_ENCP_VIDEO_VSO_BEGIN, 0x1E); + hd_write_reg(P_ENCP_VIDEO_VSO_END, 0x32); + hd_write_reg(P_ENCP_VIDEO_VSO_BLINE, 0x0); + hd_write_reg(P_ENCP_VIDEO_VSO_ELINE, custom_timing->v_sync); + hd_write_reg(P_ENCP_VIDEO_EN, 1); + hd_write_reg(P_ENCI_VIDEO_EN, 0); +} + static inline void setreg(const struct reg_s *r) { hd_write_reg(r->reg, r->val); @@ -1450,17 +1482,26 @@ static const struct reg_s *tvregs_setting_mode(struct hdmitx_dev *hdev) void set_vmode_enc_hw(struct hdmitx_dev *hdev) { - const struct reg_s *s = tvregs_setting_mode(hdev); - /* Turn off VDAC, no need any more for HDMITX */ + const struct reg_s *s; - /*hd_set_reg_bits(P_VENC_VDAC_SETTING, 0x1f, 0, 5);*/ - if (s) { - pr_info("set enc for VIC: %d\n", - hdev->cur_video_param->VIC); - while (s->reg != MREG_END_MARKER) - setreg(s++); - } else - pr_info("set enc not find VIC: %d\n", - hdev->cur_video_param->VIC); + if (hdev->cur_video_param->VIC != HDMI_CUSTOMBUILT) { + s = tvregs_setting_mode(hdev); + + /* Turn off VDAC, no need any more for HDMITX */ + /*hd_set_reg_bits(P_VENC_VDAC_SETTING, 0x1f, 0, 5);*/ + if (s) { + pr_info("set enc for VIC: %d\n", + hdev->cur_video_param->VIC); + while (s->reg != MREG_END_MARKER) + setreg(s++); + } else + pr_info("set enc not find VIC: %d\n", + hdev->cur_video_param->VIC); + } else { + /* Turn off VDAC, no need any more for HDMITX */ + /*hd_set_reg_bits(P_VENC_VDAC_SETTING, 0x1f, 0, 5);*/ + + build_custom_vic_tvregs(); + } } diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c index 7a1a44b475c1..b96981b8beaa 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c @@ -1312,6 +1312,8 @@ static void hdmi_tvenc_set(struct hdmitx_vidpara *param) unsigned long vs_bline_evn = 0, vs_eline_evn = 0; unsigned long vso_begin_evn = 0; + struct hdmi_cea_timing *custom_timing; + switch (param->VIC) { case HDMI_3840x1080p120hz: INTERLACE_MODE = 0U; @@ -1780,6 +1782,23 @@ static void hdmi_tvenc_set(struct hdmitx_vidpara *param) SOF_LINES = 29; TOTAL_FRAMES = 4; break; + case HDMI_CUSTOMBUILT: + custom_timing = get_custom_timing(); + INTERLACE_MODE = 0U; + PIXEL_REPEAT_VENC = 0; + PIXEL_REPEAT_HDMI = 0; + ACTIVE_PIXELS = custom_timing->h_active; + ACTIVE_LINES = custom_timing->v_active; + LINES_F0 = custom_timing->v_total; + LINES_F1 = custom_timing->v_total; + FRONT_PORCH = custom_timing->h_front; + HSYNC_PIXELS = custom_timing->h_sync; + BACK_PORCH = custom_timing->h_back; + EOF_LINES = custom_timing->v_front; + VSYNC_LINES = custom_timing->v_sync; + SOF_LINES = custom_timing->v_back; + TOTAL_FRAMES = 4; + break; default: break; } diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c index c8068820d0f5..7ba3558e0dc5 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c @@ -835,6 +835,10 @@ static struct hw_enc_clk_val_group setting_enc_clk_val_24[] = { {{HDMI_480x800p60_4x3, HDMI_VIC_END}, 2560000, 4, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, + {{HDMI_CUSTOMBUILT, + HDMI_VIC_END}, + /* default 1080p60hz */ + 5940000, 4, 1, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, {{HDMI_VIC_FAKE, HDMI_VIC_END}, 3450000, 1, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, @@ -962,6 +966,7 @@ static void hdmitx_set_clk_(struct hdmitx_dev *hdev) enum hdmi_vic vic = hdev->cur_VIC; enum hdmi_color_space cs = hdev->para->cs; enum hdmi_color_depth cd = hdev->para->cd; + struct hdmi_cea_timing *custom_timing; /* YUV 422 always use 24B mode */ if (cs == COLORSPACE_YUV422) @@ -1032,6 +1037,17 @@ static void hdmitx_set_clk_(struct hdmitx_dev *hdev) return; } next: + /* FIXME : consider pixel clocks over 200MHz */ + if (vic == HDMI_CUSTOMBUILT) { + pr_info("[n2][%s] vic == HDMI_CUSTOMBUILT\n", __func__); + custom_timing = get_custom_timing(); + p_enc[j].hpll_clk_out = (custom_timing->frac_freq * 10); + /* control od dividers */ + p_enc[j].od1 = 1; + p_enc[j].od2 = 1; + p_enc[j].od3 = 2; + } + hdmitx_set_cts_sys_clk(hdev); set_hpll_clk_out(p_enc[j].hpll_clk_out); if ((cd == COLORDEPTH_24B) && (hdev->sspll)) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c index 0cda696a4b3b..658c5bfad46a 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c @@ -166,6 +166,7 @@ static bool set_hpll_hclk_v3(unsigned int m, unsigned int frac_val) void set_g12a_hpll_clk_out(unsigned int frac_rate, unsigned int clk) { + unsigned int m, m1, m2; switch (clk) { case 5940000: @@ -489,6 +490,28 @@ void set_g12a_hpll_clk_out(unsigned int frac_rate, unsigned int clk) break; default: pr_info("error hpll clk: %d\n", clk); + + /* FIXME : consider pixel clocks over 200MHz */ + /* calculate "m" */ + m1 = (clk * 0x3A) / 1422000; + m2 = (clk * 0xE1) / 5405400; + m = (m1 + m2)/2; + m &= 0xff; + m |= 0x3b000400; + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, m); + pr_info("m1 0x%x, m2 0x%x, m 0x%x\n", m1, m2, m); + + /* check pll LOCK time */ + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00018000); + + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x0a691c00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x33771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39270000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); break; } } diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h index e21b50e3dd50..50598de3d62c 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h @@ -162,6 +162,7 @@ enum hdmi_vic { HDMI_800x480p60_5x3, HDMI_480x320p60_4x3, HDMI_480x800p60_4x3, + HDMI_CUSTOMBUILT, /* * the following vic is for those y420 mode diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h index 5ef3d54b0b54..173d0220b45b 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h @@ -758,6 +758,7 @@ struct Hdcp_Sub { unsigned int hdcp_sub_addr_start; unsigned int hdcp_sub_len; }; +extern struct hdmi_cea_timing *get_custom_timing(void); extern void setup_attr(const char *buf); extern unsigned int hd_read_reg(unsigned int addr); extern void hd_write_reg(unsigned int addr, unsigned int val);