From 3064eec08bb44926b28a690b398662a8e2b55cb9 Mon Sep 17 00:00:00 2001 From: Zheng Yang Date: Fri, 29 Jan 2016 15:43:28 +0800 Subject: [PATCH] video: rockchip: hdmi: sync to develop-3.10 HDMI driver sync to develop-3.10 following commit: commit 10dfac7372fb980c950d0405ee7bf175e089bf2f Author: Zheng Yang Date: Thu Jan 28 15:30:19 2016 +0800 video: rockchip: hdmi: rename some vic which pic aspect is 21:9 Use picture aspect ratio define vic, instead of pixel aspect ratio. Change-Id: I488520a1bf42d228936806e17f19f00b4579008d Signed-off-by: Zheng Yang --- .../video/rockchip/hdmi/rockchip-hdmi-cec.c | 12 +- .../video/rockchip/hdmi/rockchip-hdmi-core.c | 47 +- .../video/rockchip/hdmi/rockchip-hdmi-edid.c | 43 +- .../video/rockchip/hdmi/rockchip-hdmi-lcdc.c | 853 ++++++++++++++++-- .../video/rockchip/hdmi/rockchip-hdmi-sysfs.c | 12 +- drivers/video/rockchip/hdmi/rockchip-hdmi.h | 94 +- .../hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c | 3 +- .../rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c | 24 +- .../hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c | 90 +- .../hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h | 45 +- .../hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c | 174 ++-- .../hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h | 17 +- .../rockchip-hdmiv2/rockchip_hdmiv2_cec.c | 9 + .../rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c | 5 +- .../hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c | 474 ++++++---- .../hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h | 105 ++- 16 files changed, 1480 insertions(+), 527 deletions(-) diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c index f7e25f844245..474449ecdbbe 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-cec.c @@ -42,10 +42,8 @@ static void cecworkfunc(struct work_struct *work) break; case EVENT_RX_FRAME: list_node = kmalloc(sizeof(*list_node), GFP_KERNEL); - if (list_node == NULL) { - pr_err("HDMI CEC: list kmalloc fail! "); + if (!list_node) return; - } cecreadframe(&list_node->cecframe); if (cec_dev->enable) { mutex_lock(&cec_dev->cec_lock); @@ -72,6 +70,9 @@ void rockchip_hdmi_cec_submit_work(int event, int delay, void *data) CECDBG("%s event %04x delay %d\n", __func__, event, delay); + if (!cec_dev) + return; + work = kmalloc(sizeof(*work), GFP_ATOMIC); if (work) { @@ -252,10 +253,9 @@ int rockchip_hdmi_cec_init(struct hdmi *hdmi, int ret, i; cec_dev = kmalloc(sizeof(*cec_dev), GFP_KERNEL); - if (!cec_dev) { - pr_err("HDMI CEC: kmalloc fail!"); + if (!cec_dev) return -ENOMEM; - } + memset(cec_dev, 0, sizeof(struct cec_device)); mutex_init(&cec_dev->cec_lock); INIT_LIST_HEAD(&cec_dev->ceclist); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c index 99fd73fadcb7..8a4fa4816500 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c @@ -86,7 +86,7 @@ static void hdmi_wq_set_video(struct hdmi *hdmi) video->sink_hdmi = hdmi->edid.sink_hdmi; video->format_3d = hdmi->mode_3d; video->colorimetry = hdmi->colorimetry; - + video->color_output_depth = 8; if (hdmi->autoset) hdmi->vic = hdmi_find_best_mode(hdmi, 0); else @@ -120,14 +120,12 @@ static void hdmi_wq_set_video(struct hdmi *hdmi) (hdmi->colordepth == HDMI_DEPP_COLOR_AUTO || hdmi->colordepth == 10)) video->color_output_depth = 10; - else - video->color_output_depth = 8; } pr_info("hdmi output corlor mode is %d\n", video->color_output); if ((hdmi->property->feature & SUPPORT_YCBCR_INPUT) && (video->color_output == HDMI_COLOR_YCBCR444 || video->color_output == HDMI_COLOR_YCBCR422)) - video->color_input = HDMI_COLOR_YCBCR444; + video->color_input = HDMI_COLOR_YCBCR444; else if (video->color_output == HDMI_COLOR_YCBCR420) video->color_input = HDMI_COLOR_YCBCR420; else @@ -161,10 +159,7 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) INIT_LIST_HEAD(&pedid->modelist); pedid->raw[0] = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL); - if (pedid->raw[0] == NULL) { - dev_err(hdmi->dev, - "[%s] can not allocate memory for edid buff.\n", - __func__); + if (!pedid->raw[0]) { rc = HDMI_ERROR_FALSE; goto out; } @@ -178,7 +173,7 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) for (trytimes = 0; trytimes < 3; trytimes++) { if (trytimes) msleep(50); - memset(pedid->raw[0], 0 , HDMI_EDID_BLOCK_SIZE); + memset(pedid->raw[0], 0, HDMI_EDID_BLOCK_SIZE); rc = hdmi->ops->getedid(hdmi, 0, pedid->raw[0]); if (rc) { dev_err(hdmi->dev, @@ -210,7 +205,7 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) for (trytimes = 0; trytimes < 3; trytimes++) { if (trytimes) msleep(20); - memset(pedid->raw[i], 0 , HDMI_EDID_BLOCK_SIZE); + memset(pedid->raw[i], 0, HDMI_EDID_BLOCK_SIZE); rc = hdmi->ops->getedid(hdmi, i, pedid->raw[i]); if (rc) { dev_err(hdmi->dev, @@ -485,10 +480,9 @@ struct hdmi *rockchip_hdmi_register(struct hdmi_property *property, property->videosrc, property->display); hdmi = kmalloc(sizeof(*hdmi), GFP_KERNEL); - if (!hdmi) { - pr_err("HDMI: no memory to allocate hdmi device.\n"); + if (!hdmi) return NULL; - } + memset(hdmi, 0, sizeof(struct hdmi)); mutex_init(&hdmi->lock); @@ -520,13 +514,13 @@ struct hdmi *rockchip_hdmi_register(struct hdmi_property *property, hdmi->audio.word_length = HDMI_AUDIO_DEFAULT_WORDLENGTH; hdmi->xscale = 100; hdmi->yscale = 100; - hdmi_init_modelist(hdmi); if (hdmi->property->videosrc == DISPLAY_SOURCE_LCDC0) hdmi->lcdc = rk_get_lcdc_drv("lcdc0"); else hdmi->lcdc = rk_get_lcdc_drv("lcdc1"); - + if (!hdmi->lcdc) + goto err_create_wq; if (hdmi->lcdc->prop == EXTEND) hdmi->property->display = DISPLAY_AUX; else @@ -544,6 +538,7 @@ struct hdmi *rockchip_hdmi_register(struct hdmi_property *property, goto err_register_display; } hdmi->id = i; + hdmi_init_modelist(hdmi); #ifdef CONFIG_SWITCH if (hdmi->id == 0) { hdmi->switchdev.name = "hdmi"; @@ -610,26 +605,6 @@ int hdmi_config_audio(struct hdmi_audio *audio) if (ref_info[i].ref == 0) continue; hdmi = ref_info[i].hdmi; - - /* - if (memcmp(audio, &hdmi->audio, sizeof(struct hdmi_audio)) == 0) - continue; - */ - /*for (j = 0; j < hdmi->edid.audio_num; j++) { - if (audio->type == hdmi->edid.audio_num) - break; - }*/ - - /*if ( (j == hdmi->edid.audio_num) || - (audio->channel > hdmi->edid.audio[j].channel) || - ((audio->rate & hdmi->edid.audio[j].rate) == 0)|| - ((audio->type == HDMI_AUDIO_LPCM) && - ((audio->word_length & - hdmi->edid.audio[j].word_length) == 0)) ) { - pr_warn("[%s] warning : input audio type - not supported in hdmi sink\n", __func__); - continue; - }*/ memcpy(&hdmi->audio, audio, sizeof(struct hdmi_audio)); if (hdmi->hotplug == HDMI_HPD_ACTIVED) hdmi_submit_work(hdmi, HDMI_SET_AUDIO, 0, 0); @@ -671,7 +646,7 @@ int snd_config_hdmi_audio(struct snd_pcm_hw_params *params) audio_cfg.rate = rate; - if (HW_PARAMS_FLAG_NLPCM == params->flags) + if (params->flags == HW_PARAMS_FLAG_NLPCM) audio_cfg.type = HDMI_AUDIO_NLPCM; else audio_cfg.type = HDMI_AUDIO_LPCM; diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c index 1ade35096198..4c86d2461120 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c @@ -34,18 +34,16 @@ static int hdmi_edid_checksum(unsigned char *buf) } /* - @Des Parse Detail Timing Descriptor. - @Param buf : pointer to DTD data. - @Param pvic: VIC of DTD descripted. + * @Des Parse Detail Timing Descriptor. + * @Param buf : pointer to DTD data. + * @Param pvic: VIC of DTD descripted. */ static int hdmi_edid_parse_dtd(unsigned char *block, struct fb_videomode *mode) { mode->xres = H_ACTIVE; mode->yres = V_ACTIVE; mode->pixclock = PIXEL_CLOCK; -/* mode->pixclock /= 1000; - mode->pixclock = KHZ2PICOS(mode->pixclock); -*/ mode->right_margin = H_SYNC_OFFSET; + mode->right_margin = H_SYNC_OFFSET; mode->left_margin = (H_ACTIVE + H_BLANKING) - (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - @@ -122,8 +120,12 @@ int hdmi_edid_parse_base(unsigned char *buf, fb_edid_to_monspecs(buf, pedid->specs); out: + /* For some sink, edid checksum is failed because several + * byte is wrong. To fix this case, we think it is a good + * edid if 1 <= *extend_num <= 4. + */ if ((rc != E_HDMI_EDID_SUCCESS) && - (*extend_num < 1 && *extend_num > 4)) + (*extend_num < 1 || *extend_num > 4)) return rc; else return E_HDMI_EDID_SUCCESS; @@ -141,15 +143,7 @@ static int hdmi_edid_get_cea_svd(unsigned char *buf, struct hdmi_edid *pedid) vic = buf[1 + i] & 0x7f; hdmi_add_vic(vic, &pedid->modelist); } -/* - struct list_head *pos; - struct display_modelist *modelist; - - list_for_each(pos, &pedid->modelist) { - modelist = list_entry(pos, struct display_modelist, list); - pr_info("%s vic %d\n", __FUNCTION__, modelist->vic); - } -*/ return 0; + return 0; } /* Parse CEA Short Audio Descriptor */ @@ -169,11 +163,7 @@ static int hdmi_edid_parse_cea_sad(unsigned char *buf, struct hdmi_edid *pedid) pedid->audio[i].rate = buf[1 + i*3 + 1]; if (pedid->audio[i].type == HDMI_AUDIO_LPCM) pedid->audio[i].word_length = buf[1 + i*3 + 2]; - -/* pr_info("type %d channel %d rate %d word length %d\n", - pedid->audio[i].type, pedid->audio[i].channel, - pedid->audio[i].rate, pedid->audio[i].word_length); -*/ } + } return E_HDMI_EDID_SUCCESS; } @@ -376,7 +366,6 @@ static int hdmi_edid_parse_extensions_cea(unsigned char *buf, { unsigned int ddc_offset, native_dtd_num, cur_offset = 4; unsigned int tag, IEEEOUI = 0, count, i; -/* unsigned int underscan_support, baseaudio_support; */ if (buf == NULL) return E_HDMI_EDID_PARAM; @@ -388,17 +377,11 @@ static int hdmi_edid_parse_extensions_cea(unsigned char *buf, } ddc_offset = buf[2]; -/* underscan_support = (buf[3] >> 7) & 0x01; -*/ pedid->baseaudio_support = (buf[3] >> 6) & 0x01; + pedid->baseaudio_support = (buf[3] >> 6) & 0x01; pedid->ycbcr444 = (buf[3] >> 5) & 0x01; pedid->ycbcr422 = (buf[3] >> 4) & 0x01; native_dtd_num = buf[3] & 0x0F; -/* EDBG("[CEA] ddc_offset %d underscan_support %d - baseaudio_support %d yuv_support %d - native_dtd_num %d\n", - ddc_offset, underscan_support, baseaudio_support, - yuv_support, native_dtd_num); -*/ /* Parse data block */ + /* Parse data block */ while (cur_offset < ddc_offset) { tag = buf[cur_offset] >> 5; count = buf[cur_offset] & 0x1F; diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c index 9e7b8761c88e..1842f3f5f39d 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c @@ -1,43 +1,776 @@ #include "rockchip-hdmi.h" static const struct hdmi_video_timing hdmi_mode[] = { -/* name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag vic 2ndvic pixelrepeat interface */ - - { { "720x480i@60Hz", 60, 720, 480, 27000000, 57, 19, 15, 4, 62, 3, 0, 1, 0 }, 6, HDMI_720X480I_60HZ_16_9, 2, OUT_P888}, - { { "720x576i@50Hz", 50, 720, 576, 27000000, 69, 12, 19, 2, 63, 3, 0, 1, 0 }, 21, HDMI_720X576I_50HZ_16_9, 2, OUT_P888}, - { { "720x480p@60Hz", 60, 720, 480, 27000000, 60, 16, 30, 9, 62, 6, 0, 0, 0 }, 2, HDMI_720X480P_60HZ_16_9, 1, OUT_P888}, - { { "720x576p@50Hz", 50, 720, 576, 27000000, 68, 12, 39, 5, 64, 5, 0, 0, 0 }, 17, HDMI_720X576P_50HZ_16_9, 1, OUT_P888}, - { { "1280x720p@24Hz", 24, 1280, 720, 59400000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 60, HDMI_1280X720P_24HZ_4_3, 1, OUT_P888}, - { { "1280x720p@25Hz", 25, 1280, 720, 74250000, 220, 2420, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 61, HDMI_1280X720P_25HZ_4_3, 1, OUT_P888}, - { { "1280x720p@30Hz", 30, 1280, 720, 74250000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 62, HDMI_1280X720P_30HZ_4_3, 1, OUT_P888}, - { { "1280x720p@50Hz", 50, 1280, 720, 74250000, 220, 440, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 19, HDMI_1280X720P_50HZ_4_3, 1, OUT_P888}, - { { "1280x720p@60Hz", 60, 1280, 720, 74250000, 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 4, HDMI_1280X720P_60HZ_4_3, 1, OUT_P888}, - { { "1920x1080i@50Hz", 50, 1920, 1080, 74250000, 148, 528, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 0 }, 20, 0, 1, OUT_P888}, - { { "1920x1080i@60Hz", 60, 1920, 1080, 74250000, 148, 88, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 0 }, 5, 0, 1, OUT_P888}, - { { "1920x1080p@24Hz", 24, 1920, 1080, 74250000, 148, 638, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 32, HDMI_1920X1080P_24HZ_4_3, 1, OUT_P888}, - { { "1920x1080p@25Hz", 25, 1920, 1080, 74250000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 33, HDMI_1920X1080P_25HZ_4_3, 1, OUT_P888}, - { { "1920x1080p@30Hz", 30, 1920, 1080, 74250000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 34, HDMI_1920X1080P_30HZ_4_3, 1, OUT_P888}, - { { "1920x1080p@50Hz", 50, 1920, 1080, 148500000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 31, HDMI_1920X1080P_50HZ_4_3, 1, OUT_P888}, - { { "1920x1080p@60Hz", 60, 1920, 1080, 148500000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 16, HDMI_1920X1080P_60HZ_4_3, 1, OUT_P888}, - { { "3840x2160p@24Hz", 24, 3840, 2160, 297000000, 296, 1276, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 93, HDMI_3840X2160P_24HZ_4_3, 1, OUT_P888}, - { { "3840x2160p@25Hz", 25, 3840, 2160, 297000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 94, HDMI_3840X2160P_25HZ_4_3, 1, OUT_P888}, - { { "3840x2160p@30Hz", 30, 3840, 2160, 297000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 95, HDMI_3840X2160P_30HZ_4_3, 1, OUT_P888}, - { { "4096x2160p@24Hz", 24, 4096, 2160, 297000000, 296, 1020, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 98, 0, 1, OUT_P888}, - { { "4096x2160p@25Hz", 25, 4096, 2160, 297000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 99, 0, 1, OUT_P888}, - { { "4096x2160p@30Hz", 30, 4096, 2160, 297000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 100, 0, 1, OUT_P888}, - { { "3840x2160p@50Hz", 50, 3840, 2160, 594000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 96, HDMI_3840X2160P_50HZ_4_3, 1, OUT_P888}, - { { "3840x2160p@60Hz", 60, 3840, 2160, 594000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 97, HDMI_3840X2160P_60HZ_4_3, 1, OUT_P888}, - { { "4096x2160p@50Hz", 50, 4096, 2160, 594000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 101, 0, 1, OUT_P888}, - { { "4096x2160p@60Hz", 60, 4096, 2160, 594000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 102, 0, 1, OUT_P888}, - { { "800x600p@60Hz", 60, 800, 600, 40000000, 88, 40, 23, 1, 128, 4, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 1 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1024x768p@60Hz", 60, 1024, 768, 65000000, 160, 24, 29, 3, 136, 6, 0, 0, 0 }, 2 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1280x960p@60Hz", 60, 1280, 960, 108000000, 312, 96, 36, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 3 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1280x1024p@60Hz", 60, 1280, 1024, 108000000, 248, 48, 38, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 4 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1360x768p@60Hz", 60, 1360, 768, 85500000, 256, 64, 18, 3, 112, 6, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 5 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1366x768p@60Hz", 60, 1366, 768, 85500000, 213, 70, 24, 3, 143, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 6 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1440x900p@60Hz", 60, 1440, 900, 106500000, 232, 80, 25, 3, 152, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 7 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1600x900p@60Hz", 60, 1600, 900, 108000000, 96, 24, 96, 1, 80, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 8 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, - { { "1680x1050@60Hz", 60, 1680, 1050, 146250000, 280, 104, 30, 3, 176, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 9 | HDMI_VIDEO_DMT, 0, 1, OUT_P888}, + { + .mode = { + .name = "720x480i@60Hz", + .refresh = 60, + .xres = 720, + .yres = 480, + .pixclock = 27000000, + .left_margin = 57, + .right_margin = 19, + .upper_margin = 15, + .lower_margin = 4, + .hsync_len = 62, + .vsync_len = 3, + .sync = 0, + .vmode = FB_VMODE_INTERLACED, + .flag = 0, + }, + .vic = HDMI_720X480I_60HZ_4_3, + .vic_2nd = HDMI_720X480I_60HZ_16_9, + .pixelrepeat = 2, + .interface = OUT_P888, + }, + { + .mode = { + .name = "720x576i@50Hz", + .refresh = 50, + .xres = 720, + .yres = 576, + .pixclock = 27000000, + .left_margin = 69, + .right_margin = 12, + .upper_margin = 19, + .lower_margin = 2, + .hsync_len = 63, + .vsync_len = 3, + .sync = 0, + .vmode = FB_VMODE_INTERLACED, + .flag = 0, + }, + .vic = HDMI_720X576I_50HZ_4_3, + .vic_2nd = HDMI_720X576I_50HZ_16_9, + .pixelrepeat = 2, + .interface = OUT_P888, + }, + { + .mode = { + .name = "720x480p@60Hz", + .refresh = 60, + .xres = 720, + .yres = 480, + .pixclock = 27000000, + .left_margin = 60, + .right_margin = 16, + .upper_margin = 30, + .lower_margin = 9, + .hsync_len = 62, + .vsync_len = 6, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_720X480P_60HZ_4_3, + .vic_2nd = HDMI_720X480P_60HZ_16_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "720x576p@50Hz", + .refresh = 50, + .xres = 720, + .yres = 576, + .pixclock = 27000000, + .left_margin = 68, + .right_margin = 12, + .upper_margin = 39, + .lower_margin = 5, + .hsync_len = 64, + .vsync_len = 5, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_720X576P_50HZ_4_3, + .vic_2nd = HDMI_720X576P_50HZ_16_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1280x720p@24Hz", + .refresh = 24, + .xres = 1280, + .yres = 720, + .pixclock = 59400000, + .left_margin = 220, + .right_margin = 1760, + .upper_margin = 20, + .lower_margin = 5, + .hsync_len = 40, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1280X720P_24HZ, + .vic_2nd = HDMI_1280X720P_24HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1280x720p@25Hz", + .refresh = 25, + .xres = 1280, + .yres = 720, + .pixclock = 74250000, + .left_margin = 220, + .right_margin = 2420, + .upper_margin = 20, + .lower_margin = 5, + .hsync_len = 40, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1280X720P_25HZ, + .vic_2nd = HDMI_1280X720P_25HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1280x720p@30Hz", + .refresh = 30, + .xres = 1280, + .yres = 720, + .pixclock = 74250000, + .left_margin = 220, + .right_margin = 1760, + .upper_margin = 20, + .lower_margin = 5, + .hsync_len = 40, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1280X720P_30HZ, + .vic_2nd = HDMI_1280X720P_30HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1280x720p@50Hz", + .refresh = 50, + .xres = 1280, + .yres = 720, + .pixclock = 74250000, + .left_margin = 220, + .right_margin = 440, + .upper_margin = 20, + .lower_margin = 5, + .hsync_len = 40, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1280X720P_50HZ, + .vic_2nd = HDMI_1280X720P_50HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1280x720p@60Hz", + .refresh = 60, + .xres = 1280, + .yres = 720, + .pixclock = 74250000, + .left_margin = 220, + .right_margin = 110, + .upper_margin = 20, + .lower_margin = 5, + .hsync_len = 40, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1280X720P_60HZ, + .vic_2nd = HDMI_1280X720P_60HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1920x1080i@50Hz", + .refresh = 50, + .xres = 1920, + .yres = 1080, + .pixclock = 74250000, + .left_margin = 148, + .right_margin = 528, + .upper_margin = 15, + .lower_margin = 2, + .hsync_len = 44, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_INTERLACED, + .flag = 0, + }, + .vic = HDMI_1920X1080I_50HZ, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1920x1080i@60Hz", + .refresh = 60, + .xres = 1920, + .yres = 1080, + .pixclock = 74250000, + .left_margin = 148, + .right_margin = 88, + .upper_margin = 15, + .lower_margin = 2, + .hsync_len = 44, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_INTERLACED, + .flag = 0, + }, + .vic = HDMI_1920X1080I_60HZ, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1920x1080p@24Hz", + .refresh = 24, + .xres = 1920, + .yres = 1080, + .pixclock = 74250000, + .left_margin = 148, + .right_margin = 638, + .upper_margin = 36, + .lower_margin = 4, + .hsync_len = 44, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1920X1080P_24HZ, + .vic_2nd = HDMI_1920X1080P_24HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1920x1080p@25Hz", + .refresh = 25, + .xres = 1920, + .yres = 1080, + .pixclock = 74250000, + .left_margin = 148, + .right_margin = 528, + .upper_margin = 36, + .lower_margin = 4, + .hsync_len = 44, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1920X1080P_25HZ, + .vic_2nd = HDMI_1920X1080P_25HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1920x1080p@30Hz", + .refresh = 30, + .xres = 1920, + .yres = 1080, + .pixclock = 74250000, + .left_margin = 148, + .right_margin = 88, + .upper_margin = 36, + .lower_margin = 4, + .hsync_len = 44, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1920X1080P_30HZ, + .vic_2nd = HDMI_1920X1080P_30HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1920x1080p@50Hz", + .refresh = 50, + .xres = 1920, + .yres = 1080, + .pixclock = 148500000, + .left_margin = 148, + .right_margin = 528, + .upper_margin = 36, + .lower_margin = 4, + .hsync_len = 44, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1920X1080P_50HZ, + .vic_2nd = HDMI_1920X1080P_50HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1920x1080p@60Hz", + .refresh = 60, + .xres = 1920, + .yres = 1080, + .pixclock = 148500000, + .left_margin = 148, + .right_margin = 88, + .upper_margin = 36, + .lower_margin = 4, + .hsync_len = 44, + .vsync_len = 5, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_1920X1080P_60HZ, + .vic_2nd = HDMI_1920X1080P_60HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "3840x2160p@24Hz", + .refresh = 24, + .xres = 3840, + .yres = 2160, + .pixclock = 297000000, + .left_margin = 296, + .right_margin = 1276, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_3840X2160P_24HZ, + .vic_2nd = HDMI_3840X2160P_24HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "3840x2160p@25Hz", + .refresh = 25, + .xres = 3840, + .yres = 2160, + .pixclock = 297000000, + .left_margin = 296, + .right_margin = 1056, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_3840X2160P_25HZ, + .vic_2nd = HDMI_3840X2160P_25HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "3840x2160p@30Hz", + .refresh = 30, + .xres = 3840, + .yres = 2160, + .pixclock = 297000000, + .left_margin = 296, + .right_margin = 176, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_3840X2160P_30HZ, + .vic_2nd = HDMI_3840X2160P_30HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "4096x2160p@24Hz", + .refresh = 24, + .xres = 4096, + .yres = 2160, + .pixclock = 297000000, + .left_margin = 296, + .right_margin = 1020, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_4096X2160P_24HZ, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "4096x2160p@25Hz", + .refresh = 25, + .xres = 4096, + .yres = 2160, + .pixclock = 297000000, + .left_margin = 128, + .right_margin = 968, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_4096X2160P_25HZ, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "4096x2160p@30Hz", + .refresh = 30, + .xres = 4096, + .yres = 2160, + .pixclock = 297000000, + .left_margin = 128, + .right_margin = 88, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_4096X2160P_30HZ, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "3840x2160p@50Hz", + .refresh = 50, + .xres = 3840, + .yres = 2160, + .pixclock = 594000000, + .left_margin = 296, + .right_margin = 1056, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_3840X2160P_50HZ, + .vic_2nd = HDMI_3840X2160P_50HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "3840x2160p@60Hz", + .refresh = 60, + .xres = 3840, + .yres = 2160, + .pixclock = 594000000, + .left_margin = 296, + .right_margin = 176, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_3840X2160P_60HZ, + .vic_2nd = HDMI_3840X2160P_60HZ_21_9, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "4096x2160p@50Hz", + .refresh = 50, + .xres = 4096, + .yres = 2160, + .pixclock = 594000000, + .left_margin = 128, + .right_margin = 968, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_4096X2160P_50HZ, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "4096x2160p@60Hz", + .refresh = 60, + .xres = 4096, + .yres = 2160, + .pixclock = 594000000, + .left_margin = 128, + .right_margin = 88, + .upper_margin = 72, + .lower_margin = 8, + .hsync_len = 88, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_4096X2160P_60HZ, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "800x600p@60Hz", + .refresh = 60, + .xres = 800, + .yres = 600, + .pixclock = 40000000, + .left_margin = 88, + .right_margin = 40, + .upper_margin = 23, + .lower_margin = 1, + .hsync_len = 128, + .vsync_len = 4, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 1, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1024x768p@60Hz", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 65000000, + .left_margin = 160, + .right_margin = 24, + .upper_margin = 29, + .lower_margin = 3, + .hsync_len = 136, + .vsync_len = 6, + .sync = 0, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 2, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1280x960p@60Hz", + .refresh = 60, + .xres = 1280, + .yres = 960, + .pixclock = 108000000, + .left_margin = 312, + .right_margin = 96, + .upper_margin = 36, + .lower_margin = 1, + .hsync_len = 112, + .vsync_len = 3, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 3, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1280x1024p@60Hz", + .refresh = 60, + .xres = 1280, + .yres = 1024, + .pixclock = 108000000, + .left_margin = 248, + .right_margin = 48, + .upper_margin = 38, + .lower_margin = 1, + .hsync_len = 112, + .vsync_len = 3, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 4, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1360x768p@60Hz", + .refresh = 60, + .xres = 1360, + .yres = 768, + .pixclock = 85500000, + .left_margin = 256, + .right_margin = 64, + .upper_margin = 18, + .lower_margin = 3, + .hsync_len = 112, + .vsync_len = 6, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 5, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1366x768p@60Hz", + .refresh = 60, + .xres = 1366, + .yres = 768, + .pixclock = 85500000, + .left_margin = 213, + .right_margin = 70, + .upper_margin = 24, + .lower_margin = 3, + .hsync_len = 143, + .vsync_len = 3, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 6, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1440x900p@60Hz", + .refresh = 60, + .xres = 1440, + .yres = 768, + .pixclock = 106500000, + .left_margin = 232, + .right_margin = 80, + .upper_margin = 25, + .lower_margin = 3, + .hsync_len = 152, + .vsync_len = 6, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 7, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1600x900p@60Hz", + .refresh = 60, + .xres = 1600, + .yres = 900, + .pixclock = 108000000, + .left_margin = 96, + .right_margin = 24, + .upper_margin = 96, + .lower_margin = 1, + .hsync_len = 80, + .vsync_len = 3, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 8, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, + { + .mode = { + .name = "1680x1050@60Hz", + .refresh = 60, + .xres = 1680, + .yres = 1050, + .pixclock = 146250000, + .left_margin = 280, + .right_margin = 104, + .upper_margin = 30, + .lower_margin = 3, + .hsync_len = 176, + .vsync_len = 6, + .sync = FB_SYNC_VERT_HIGH_ACT, + .vmode = 0, + .flag = 0, + }, + .vic = HDMI_VIDEO_DMT | 9, + .vic_2nd = 0, + .pixelrepeat = 1, + .interface = OUT_P888, + }, }; static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi) @@ -151,7 +884,7 @@ int hdmi_find_best_mode(struct hdmi *hdmi, int vic) struct list_head *pos, *head = &hdmi->edid.modelist; struct display_modelist *modelist; int found = 0; -/* pr_info("%s vic %d\n", __FUNCTION__, vic); */ + if (vic) { list_for_each(pos, head) { modelist = @@ -163,16 +896,14 @@ int hdmi_find_best_mode(struct hdmi *hdmi, int vic) } } } - if ((vic == 0 || found == 0) && head->next != head) { + if ((!vic || !found) && head->next != head) { /* If parse edid error, we select default mode; */ - if (hdmi->edid.specs == NULL || - hdmi->edid.specs->modedb_len == 0) - return hdmi->property->defaultmode; - /*modelist = list_entry(head->prev, - struct display_modelist, list);*/ - else + if (hdmi->edid.specs && + hdmi->edid.specs->modedb_len) modelist = list_entry(head->next, struct display_modelist, list); + else + return hdmi->property->defaultmode; } if (modelist != NULL) @@ -193,14 +924,8 @@ int hdmi_set_lcdc(struct hdmi *hdmi) struct rk_screen screen; rc = hdmi_set_info(&screen, hdmi); - - if (rc == 0) { + if (!rc) rk_fb_switch_screen(&screen, 1, hdmi->lcdc->id); -/* if (rk_fb_get_display_policy() != DISPLAY_POLICY_BOX) - rk_fb_disp_scale(hdmi->xscale, - hdmi->yscale, - hdmi->lcdc->id); -*/ } return rc; } @@ -381,13 +1106,10 @@ static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature) hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED) continue; - vic = modelist->vic; - modelist->vic = hdmi_mode[i].vic; modelist->mode = hdmi_mode[i].mode; - if (vic & HDMI_VIDEO_YUV420) { - modelist->vic |= HDMI_VIDEO_YUV420; + if (modelist->vic & HDMI_VIDEO_YUV420) modelist->mode.flag = 1; - } + compare = 1; m = (struct fb_videomode *)&(modelist->mode); list_for_each(pos_new, &head_new) { @@ -451,9 +1173,9 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok) dev_info(hdmi->dev, "warning: no CEA video mode parsed from EDID !!!!\n"); /* If EDID get error, list all system supported mode. - If output mode is set to DVI and EDID is ok, check - the output timing. - */ + * If output mode is set to DVI and EDID is ok, check + * the output timing. + */ if (hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) { /* Get max resolution timing */ modedb = &specs->modedb[0]; @@ -466,8 +1188,9 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok) modedb = &specs->modedb[i]; } /* For some monitor, the max pixclock read from EDID - is smaller than the clock of max resolution mode - supported. We fix it. */ + * is smaller than the clock of max resolution mode + * supported. We fix it. + */ pixclock = PICOS2KHZ(modedb->pixclock); pixclock /= 250; pixclock *= 250; @@ -490,7 +1213,8 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok) continue; } else { /* If there is no valid information in EDID, - just list common hdmi foramt. */ + * just list common hdmi foramt. + */ if (mode->xres > 3840 || mode->refresh < 50 || (mode->vmode & FB_VMODE_INTERLACED) || @@ -518,7 +1242,8 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok) } } else { /* There are some video mode is not defined in EDID extend - block, so we need to check first block data.*/ + * block, so we need to check first block data. + */ if (specs && specs->modedb_len) { for (i = 0; i < specs->modedb_len; i++) { modedb = &specs->modedb[i]; diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c index 73e678713501..5449f50617a7 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c @@ -103,10 +103,10 @@ static int hdmi_set_3dmode(struct rk_display_device *device, int mode) list_for_each(pos, modelist) { display_modelist = list_entry(pos, struct display_modelist, list); - if (hdmi->vic == display_modelist->vic) - break; - else + if (hdmi->vic != display_modelist->vic) display_modelist = NULL; + else + break; } if (!display_modelist) return -1; @@ -133,9 +133,9 @@ static int hdmi_get_3dmode(struct rk_display_device *device) return hdmi->mode_3d; } -/*CEA 861-E: Audio Coding Type - sync width enum hdmi_audio_type -*/ +/* CEA 861-E: Audio Coding Type + * sync width enum hdmi_audio_type + */ static const char * const audioformatstr[] = { "", "LPCM", /*HDMI_AUDIO_LPCM = 1,*/ diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi.h b/drivers/video/rockchip/hdmi/rockchip-hdmi.h index aff6166dfac8..5f1460a0832b 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi.h @@ -84,20 +84,20 @@ enum hdmi_video_infomation_code { HDMI_1280X720P_30HZ, HDMI_1920X1080P_120HZ, HDMI_1920X1080P_100HZ, - HDMI_1280X720P_24HZ_4_3, /*65*/ - HDMI_1280X720P_25HZ_4_3, - HDMI_1280X720P_30HZ_4_3, - HDMI_1280X720P_50HZ_4_3, - HDMI_1280X720P_60HZ_4_3, - HDMI_1280X720P_100HZ_4_3, /*70*/ - HDMI_1280X720P_120HZ_4_3, - HDMI_1920X1080P_24HZ_4_3, - HDMI_1920X1080P_25HZ_4_3, - HDMI_1920X1080P_30HZ_4_3, - HDMI_1920X1080P_50HZ_4_3, /*75*/ - HDMI_1920X1080P_60HZ_4_3, - HDMI_1920X1080P_100HZ_4_3, - HDMI_1920X1080P_120HZ_4_3, + HDMI_1280X720P_24HZ_21_9, /*65*/ + HDMI_1280X720P_25HZ_21_9, + HDMI_1280X720P_30HZ_21_9, + HDMI_1280X720P_50HZ_21_9, + HDMI_1280X720P_60HZ_21_9, + HDMI_1280X720P_100HZ_21_9, /*70*/ + HDMI_1280X720P_120HZ_21_9, + HDMI_1920X1080P_24HZ_21_9, + HDMI_1920X1080P_25HZ_21_9, + HDMI_1920X1080P_30HZ_21_9, + HDMI_1920X1080P_50HZ_21_9, /*75*/ + HDMI_1920X1080P_60HZ_21_9, + HDMI_1920X1080P_100HZ_21_9, + HDMI_1920X1080P_120HZ_21_9, HDMI_1680X720P_24HZ, HDMI_1680X720P_25HZ, /*80*/ HDMI_1680X720P_30HZ, @@ -122,11 +122,11 @@ enum hdmi_video_infomation_code { HDMI_4096X2160P_30HZ, /*100*/ HDMI_4096X2160P_50HZ, HDMI_4096X2160P_60HZ, - HDMI_3840X2160P_24HZ_4_3, - HDMI_3840X2160P_25HZ_4_3, - HDMI_3840X2160P_30HZ_4_3, /*105*/ - HDMI_3840X2160P_50HZ_4_3, - HDMI_3840X2160P_60HZ_4_3, + HDMI_3840X2160P_24HZ_21_9, + HDMI_3840X2160P_25HZ_21_9, + HDMI_3840X2160P_30HZ_21_9, /*105*/ + HDMI_3840X2160P_50HZ_21_9, + HDMI_3840X2160P_60HZ_21_9, }; /* HDMI Extended Resolution */ @@ -230,11 +230,13 @@ enum hdmi_audio_word_length { /* HDMI Hotplug Status */ enum hdmi_hotpulg_status { - HDMI_HPD_REMOVED = 0, /* HDMI is disconnected */ - HDMI_HPD_INSERT, /* HDMI is connected, but HDP is low - or TMDS link is not pull up to 3.3V*/ - HDMI_HPD_ACTIVED /* HDMI is connected, all singnal - is normal */ + HDMI_HPD_REMOVED = 0, /* HDMI is disconnected */ + HDMI_HPD_INSERT, /* HDMI is connected, but HDP is low + * or TMDS link is not pull up to 3.3V. + */ + HDMI_HPD_ACTIVED /* HDMI is connected, all singnal + * is normal + */ }; enum hdmi_mute_status { @@ -282,18 +284,20 @@ struct hdmi_audio { #define HDMI_MAX_EDID_BLOCK 8 /* HDMI EDID Information */ struct hdmi_edid { - unsigned char sink_hdmi; /*HDMI display device flag*/ - unsigned char ycbcr444; /*Display device support YCbCr444*/ - unsigned char ycbcr422; /*Display device support YCbCr422*/ - unsigned char ycbcr420; /*Display device support YCbCr420*/ - unsigned char deepcolor; /*bit3:DC_48bit; bit2:DC_36bit; - bit1:DC_30bit; bit0:DC_Y444;*/ + unsigned char sink_hdmi; /* HDMI display device flag */ + unsigned char ycbcr444; /* Display device support YCbCr444 */ + unsigned char ycbcr422; /* Display device support YCbCr422 */ + unsigned char ycbcr420; /* Display device support YCbCr420 */ + unsigned char deepcolor; /* bit3:DC_48bit; bit2:DC_36bit; + * bit1:DC_30bit; bit0:DC_Y444; + */ unsigned char deepcolor_420; - unsigned int cecaddress; /*CEC physical address*/ - unsigned int maxtmdsclock; /*Max supported tmds clock*/ - unsigned char fields_present; /*bit7: latency - bit6: i_lantency - bit5: hdmi_video*/ + unsigned int cecaddress; /* CEC physical address */ + unsigned int maxtmdsclock; /* Max supported tmds clock */ + unsigned char fields_present; /* bit7: latency + * bit6: i_lantency + * bit5: hdmi_video + */ unsigned char video_latency; unsigned char audio_latency; unsigned char interlaced_video_latency; @@ -371,7 +375,7 @@ enum { HDMI_SOC_RK312X, HDMI_SOC_RK3288, HDMI_SOC_RK3368, - HDMI_SOC_RK3228 + HDMI_SOC_RK322X }; /* HDMI Information */ @@ -388,7 +392,7 @@ struct hdmi { struct hdmi_property *property; struct hdmi_ops *ops; - struct mutex lock; /* mutex for hdmi operation*/ + struct mutex lock; /* mutex for hdmi operation */ struct workqueue_struct *workqueue; bool uboot; /* if true, HDMI is initialized in uboot*/ @@ -396,9 +400,10 @@ struct hdmi { int hotplug; /* hot plug status*/ int autoset; /* if true, auto set hdmi output mode according EDID.*/ int mute; /* HDMI display status: - 2 means mute audio, - 1 means mute display; - 0 is unmute*/ + * 2 - mute audio, + * 1 - mute display; + * 0 - unmute + */ int colordepth; /* Output color depth*/ int colormode; /* Output color mode*/ int colorimetry; /* Output colorimetry */ @@ -439,11 +444,14 @@ struct hdmi { #define SCDC_TEST_CFG_0 0xc0 /* Test_config_0 */ #define SCDC_TEST_RESERVED 0xc1 /* 0xc1-0xcf */ #define SCDC_MAN_OUI_3RD 0xd0 /* Manufacturer IEEE OUI, - Third Octet */ + * Third Octet + */ #define SCDC_MAN_OUI_2ND 0xd1 /* Manufacturer IEEE OUI, - Second Octet */ + * Second Octet + */ #define SCDC_MAN_OUI_1ST 0xd2 /* Manufacturer IEEE OUI, - First Octet */ + * First Octet + */ #define SCDC_DEVICE_ID 0xd3 /* 0xd3-0xdd - Device ID */ #define SCDC_MAN_SPECIFIC 0xde /* 0xde-0xff - ManufacturerSpecific */ diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c index 03be0991d24c..9ce83b6b4d88 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1.c @@ -256,8 +256,7 @@ static int rockchip_hdmiv1_parse_dt(struct hdmi_dev *hdmi_dev) rockchip_hdmiv1_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE; } - /*hdmi_dev->grf_base = - syscon_regmap_lookup_by_phandle(np, "rockchip,grf");*/ + return 0; } MODULE_DEVICE_TABLE(of, rockchip_hdmiv1_dt_ids); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c index 0b067c0114c3..c8f80e5cfcaa 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hdcp.c @@ -268,10 +268,6 @@ static void rockchip_hdmiv1_hdcp_interrupt(struct hdmi_dev *hdmi_dev, if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS); -/* - hdmi_readl(HDCP_ERROR, &temp); - DBG("HDCP: Error reg 0x65 = 0x%02x\n", temp); -*/ } /*----------------------------------------------------------------------------- @@ -346,9 +342,9 @@ static void hdcp_wq_authentication_failure(void) return; rockchip_hdmiv1_hdcp_disable(hdcp->hdmi_dev); -/* - rockchip_hdmiv1_hdmi_control_output(false); - */ + + /* rockchip_hdmiv1_hdmi_control_output(false); */ + rockchip_hdmiv1_set_colorbar(hdcp->hdmi_dev, 1); hdcp_cancel_work(&hdcp->pending_wq_event); if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) { @@ -502,10 +498,12 @@ static void hdcp_work_queue(struct work_struct *work) case HDCP_DISABLED: /* HDCP enable control or re-authentication event */ if (event == HDCP_ENABLE_CTL) { - /*if (hdcp->retry_times == 0) + #if 0 + if (hdcp->retry_times == 0) hdcp->retry_cnt = HDCP_INFINITE_REAUTH; else - hdcp->retry_cnt = hdcp->retry_times;*/ + hdcp->retry_cnt = hdcp->retry_times; + #endif hdcp->retry_cnt = HDCP_INFINITE_REAUTH; if (hdcp->hdmi_state == HDMI_STARTED) hdcp_wq_start_authentication(); @@ -598,10 +596,10 @@ static void hdcp_irq_cb(int status) (hdcp->hdcp_state != HDCP_ENABLE_PENDING)) hdcp_submit_work(HDCP_FAIL_EVENT, 0); } -/* + #if 0 else if (interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE)) hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0); - */ + #endif else if (interrupt1 & m_INT_AUTH_SUCCESS) hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0); } @@ -659,10 +657,8 @@ static void hdcp_load_keys_cb(const struct firmware *fw, void *context) return; } hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL); - if (hdcp->keys == NULL) { - pr_err("HDCP: can't allocated space for keys\n"); + if (!hdcp->keys) return; - } memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE); HDCP_WARN("HDCP: load hdcp key success\n"); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c index 1a47a5b3ea3d..919234b154a6 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.c @@ -168,11 +168,6 @@ int rockchip_hdmiv1_read_edid(struct hdmi *hdmi_drv, int block, u8 *buf) hdmi_readl(hdmi_dev, 0x50, &c); buf[j] = c; checksum += c; -#ifdef HDMI_DEBUG - if (j % 16 == 0) - printk("\n>>>0x%02x: ", j); - printk("0x%02x ", c); -#endif } if ((checksum & 0xff) == 0) { @@ -195,62 +190,60 @@ int rockchip_hdmiv1_read_edid(struct hdmi *hdmi_drv, int block, u8 *buf) } static const char coeff_csc[][24] = { - /*YUV2RGB:601 SD mode(Y[16:235],UV[16:240],RGB[0:255]): - R = 1.164*Y +1.596*V - 204 - G = 1.164*Y - 0.391*U - 0.813*V + 154 - B = 1.164*Y + 2.018*U - 258*/ + /* YUV2RGB:601 SD mode(Y[16:235],UV[16:240],RGB[0:255]): + * R = 1.164*Y +1.596*V - 204 + * G = 1.164*Y - 0.391*U - 0.813*V + 154 + * B = 1.164*Y + 2.018*U - 258 + */ { 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc, 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a, 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02}, - /*YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]): - R = Y + 1.402*V - 248 - G = Y - 0.344*U - 0.714*V + 135 - B = Y + 1.772*U - 227*/ + /* YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]): + * R = Y + 1.402*V - 248 + * G = Y - 0.344*U - 0.714*V + 135 + * B = Y + 1.772*U - 227 + */ { 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8, 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87, 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3}, - /*YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]): - R = 1.164*Y +1.793*V - 248 - G = 1.164*Y - 0.213*U - 0.534*V + 77 - B = 1.164*Y + 2.115*U - 289*/ + /* YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]): + * R = 1.164*Y +1.793*V - 248 + * G = 1.164*Y - 0.213*U - 0.534*V + 77 + * B = 1.164*Y + 2.115*U - 289 + */ { 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8, 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d, 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21}, - /*RGB2YUV:601 SD mode: - Cb = -0.291G - 0.148R + 0.439B + 128 - Y = 0.504G + 0.257R + 0.098B + 16 - Cr = -0.368G + 0.439R - 0.071B + 128*/ + /* RGB2YUV:601 SD mode: + * Cb = -0.291G - 0.148R + 0.439B + 128 + * Y = 0.504G + 0.257R + 0.098B + 16 + * Cr = -0.368G + 0.439R - 0.071B + 128 + */ { - /*0x11, 0x78, 0x01, 0xc1, 0x10, 0x48, 0x00, 0x80, - 0x02, 0x04, 0x01, 0x07, 0x00, 0x64, 0x00, 0x10, - 0x11, 0x29, 0x10, 0x97, 0x01, 0xc1, 0x00, 0x80*/ - - /*0x11,0x4b,0x01,0x8a,0x10,0x3f,0x00,0x80, - 0x01,0xbb,0x00,0xe2,0x00,0x56,0x00,0x1d, - 0x11,0x05,0x10,0x85,0x01,0x8a,0x00,0x80*/ - 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80, 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e, 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80 }, - /*RGB2YUV:709 HD mode: - Cb = - 0.338G - 0.101R + 0.439B + 128 - Y = 0.614G + 0.183R + 0.062B + 16 - Cr = - 0.399G + 0.439R - 0.040B + 128*/ + /* RGB2YUV:709 HD mode: + * Cb = - 0.338G - 0.101R + 0.439B + 128 + * Y = 0.614G + 0.183R + 0.062B + 16 + * Cr = - 0.399G + 0.439R - 0.040B + 128 + */ { 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80, 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10, 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80 }, - /*RGB[0:255]2RGB[16:235]: - R' = R x (235-16)/255 + 16; - G' = G x (235-16)/255 + 16; - B' = B x (235-16)/255 + 16;*/ + /* RGB[0:255]2RGB[16:235]: + * R' = R x (235-16)/255 + 16; + * G' = G x (235-16)/255 + 16; + * B' = B x (235-16)/255 + 16; + */ { 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, @@ -453,22 +446,26 @@ static int rockchip_hdmiv1_config_vsi(struct hdmi *hdmi, /* PB4 - HDMI_Video_Format into bits 7:5 */ info[7] = format << 5; /* PB5 - Depending on the video format, this byte will contain either - the HDMI_VIC code in buts 7:0, OR the 3D_Structure in bits 7:4. */ + * the HDMI_VIC code in buts 7:0, OR the 3D_Structure in bits 7:4. + */ switch (format) { case HDMI_VIDEO_FORMAT_4KX2K: /* This is a 2x4K mode, set the HDMI_VIC in buts 7:0. Values - are from HDMI 1.4 Spec, 8.2.3.1 (Table 8-13). */ + * are from HDMI 1.4 Spec, 8.2.3.1 (Table 8-13). + */ info[2] = 0x06 - 1; info[8] = vic_3d; info[9] = 0; break; case HDMI_VIDEO_FORMAT_3D: /* This is a 3D mode, set the 3D_Structure in buts 7:4 - Bits 3:0 are reseved so set to 0. Values are from HDMI 1.4 - Spec, Appendix H (Table H-2). */ + * Bits 3:0 are reseved so set to 0. Values are from HDMI 1.4 + * Spec, Appendix H (Table H-2). + */ info[8] = vic_3d << 4; /* Add the Extended data field when the 3D format is - Side-by-Side(Half). See Spec Table H-3 for details. */ + * Side-by-Side(Half). See Spec Table H-3 for details. + */ if ((info[8] >> 4) == HDMI_3D_SIDE_BY_SIDE_HALF) { info[2] = 0x06; info[9] = 0x00; @@ -562,12 +559,6 @@ static int rockchip_hdmiv1_config_video(struct hdmi *hdmi_drv, if (hdmi_dev->soctype == HDMI_SOC_RK3036) { /*rk3036 vop only can output rgb fmt*/ vpara->color_input = HDMI_COLOR_RGB_0_255; - } else if (hdmi_dev->soctype == HDMI_SOC_RK312X) { - /* rk3128 vop can output yuv444 fmt */ - /*if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) - vpara->output_color = VIDEO_OUTPUT_YCBCR444; - else - vpara->output_color = VIDEO_OUTPUT_RGB444;*/ } mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); @@ -585,7 +576,8 @@ static int rockchip_hdmiv1_config_video(struct hdmi *hdmi_drv, v_AUDIO_MUTE(1) | v_AUDIO_PD(1) | v_VIDEO_MUTE(1)); /* Input video mode is SDR RGB24bit, - Data enable signal from external */ + * Data enable signal from external + */ hdmi_writel(hdmi_dev, VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h index b8f48d59ea00..6117a3cc1c0b 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv1/rockchip_hdmiv1_hw.h @@ -34,23 +34,28 @@ enum { /* Color Space Convertion Mode */ enum { CSC_ITU601_16_235_TO_RGB_0_255_8BIT,/* YCbCr 16-235 input to RGB - 0-255 output according BT601 - that is 8bit clolor depth */ + * 0-255 output according BT601 + * that is 8bit clolor depth + */ CSC_ITU601_0_255_TO_RGB_0_255_8BIT, /* YCbCr 0-255 input to RGB - 0-255 output according BT601 - that is 8bit clolor depth */ + * 0-255 output according BT601 + * that is 8bit clolor depth + */ CSC_ITU709_16_235_TO_RGB_0_255_8BIT,/* YCbCr 16-235 input to RGB - 0-255 output according BT709 - that is 8bit clolor depth */ + * 0-255 output according BT709 + * that is 8bit clolor depth + */ CSC_RGB_0_255_TO_ITU601_16_235_8BIT,/* RGB 0-255 input to YCbCr - 16-235 output according BT601 - that is 8bit clolor depth */ + * 16-235 output according BT601 + * that is 8bit clolor depth + */ CSC_RGB_0_255_TO_ITU709_16_235_8BIT,/* RGB 0-255 input to YCbCr 16-235 - output accroding BT709 that is - 8bit clolor depth */ + * output accroding BT709 that is + * 8bit clolor depth + */ CSC_RGB_0_255_TO_RGB_16_235_8BIT, /* RGB 0-255 input to RGB 16-235 - output that is 8bit clolor depth - */ + * output that is 8bit clolor depth + */ }; @@ -128,9 +133,10 @@ enum { #define m_SOF (1 << 3) #define m_COLOR_RANGE (1 << 2) #define m_CSC (1 << 0) -#define v_COLOR_DEPTH_NOT_INDICATED(n) ((n) << 4) /*1: Force GCP CD[3:0] zero - 0: GCP CD[3:0] according - color depth*/ +#define v_COLOR_DEPTH_NOT_INDICATED(n) ((n) << 4) /* 1: Force GCP CD[3:0] zero + * 0: GCP CD[3:0] according + * color depth + */ #define v_SOF_ENABLE (0 << 3) #define v_SOF_DISABLE (1 << 3) #define v_COLOR_RANGE_FULL (1 << 2) @@ -265,10 +271,11 @@ enum { #define PACKET_SEND_MANUAL 0x9c #define PACKET_SEND_AUTO 0x9d #define m_PACKET_GCP_EN (1 << 7) - #define m_PACKET_MSI_EN (1 << 6) /*MPEG Source InfoFrame*/ - #define m_PACKET_SDI_EN (1 << 5) /*Source product descriptor*/ - #define m_PACKET_VSI_EN (1 << 4) /*HDMI Vendor Specific - InfoFrame*/ + #define m_PACKET_MSI_EN (1 << 6) /* MPEG Source InfoFrame */ + #define m_PACKET_SDI_EN (1 << 5) /* Source product descriptor */ + #define m_PACKET_VSI_EN (1 << 4) /* HDMI Vendor Specific + * InfoFrame + */ #define v_PACKET_GCP_EN(n) ((n & 1) << 7) #define v_PACKET_MSI_EN(n) ((n & 1) << 6) #define v_PACKET_SDI_EN(n) ((n & 1) << 5) diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c index a8e8a0b5cb30..6cbf9b4b9b86 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -97,10 +98,14 @@ static ssize_t hdmi_regs_ctrl_write(struct file *file, static int hdmi_regs_phy_show(struct seq_file *s, void *v) { - u32 i; + u32 i, count; + if (hdmi_dev->soctype == HDMI_SOC_RK322X) + count = 0xff; + else + count = 0x28; seq_puts(s, "\n>>>hdmi_phy reg "); - for (i = 0; i < 0x28; i++) + for (i = 0; i < count; i++) seq_printf(s, "regs %02x val %04x\n", i, rockchip_hdmiv2_read_phy(hdmi_dev, i)); return 0; @@ -173,20 +178,53 @@ static void rockchip_hdmiv2_early_resume(struct early_suspend *h) } #endif -#define HDMI_PD_ON (1 << 0) +void ext_pll_set_27m_out(void) +{ + if (!hdmi_dev || hdmi_dev->soctype != HDMI_SOC_RK322X) + return; + /* PHY PLL VCO is 1080MHz, output pclk is 27MHz */ + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PLL_PRE_DIVIDER, + 1); + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PLL_FB_DIVIDER, + 45); + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PCLK_DIVIDER1, + 0x61); + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PCLK_DIVIDER2, + 0x64); + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_TMDSCLK_DIVIDER, + 0x1d); +} + +#define HDMI_PD_ON (1 << 0) #define HDMI_PCLK_ON (1 << 1) #define HDMI_HDCPCLK_ON (1 << 2) #define HDMI_CECCLK_ON (1 << 3) +#define HDMI_EXT_PHY_CLK_ON (1 << 4) static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev) { - if ((hdmi_dev->clk_on & HDMI_PD_ON) && - (hdmi_dev->clk_on & HDMI_PCLK_ON) && - (hdmi_dev->clk_on & HDMI_HDCPCLK_ON)) - return 0; - - if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) { - if (hdmi_dev->pd == NULL) { + if (hdmi_dev->soctype == HDMI_SOC_RK322X) { + if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) == 0) { + if (!hdmi_dev->pclk_phy) { + hdmi_dev->pclk_phy = + devm_clk_get(hdmi_dev->dev, + "pclk_hdmi_phy"); + if (IS_ERR(hdmi_dev->pclk_phy)) { + dev_err(hdmi_dev->dev, + "get hdmi phy pclk error\n"); + return -1; + } + } + clk_prepare_enable(hdmi_dev->pclk_phy); + hdmi_dev->clk_on |= HDMI_EXT_PHY_CLK_ON; + } + } else if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) { + if (!hdmi_dev->pd) { hdmi_dev->pd = devm_clk_get(hdmi_dev->dev, "pd_hdmi"); if (IS_ERR(hdmi_dev->pd)) { dev_err(hdmi_dev->dev, @@ -265,6 +303,11 @@ static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev) hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON; } + if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) && + hdmi_dev->pclk_phy) { + clk_disable_unprepare(hdmi_dev->pclk_phy); + hdmi_dev->clk_on &= ~HDMI_EXT_PHY_CLK_ON; + } return 0; } @@ -351,22 +394,13 @@ static void rockchip_hdmiv2_irq_work_func(struct work_struct *work) } #endif -static irqreturn_t rockchip_hdmiv2_gpio_hpd_irq(int irq, void *priv) -{ - struct hdmi_dev *hdmi_dev = priv; - struct hdmi *hdmi = hdmi_dev->hdmi; - - hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 20, 0); - return IRQ_HANDLED; -} - static struct hdmi_ops rk_hdmi_ops; #if defined(CONFIG_OF) static const struct of_device_id rk_hdmi_dt_ids[] = { {.compatible = "rockchip,rk3288-hdmi",}, {.compatible = "rockchip,rk3368-hdmi",}, - {.compatible = "rockchip,rk3228-hdmi",}, + {.compatible = "rockchip,rk322x-hdmi",}, {} }; @@ -384,25 +418,13 @@ static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev) hdmi_dev->soctype = HDMI_SOC_RK3288; } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) { hdmi_dev->soctype = HDMI_SOC_RK3368; - } else if (!strcmp(match->compatible, "rockchip,rk3228-hdmi")) { - hdmi_dev->soctype = HDMI_SOC_RK3228; + } else if (!strcmp(match->compatible, "rockchip,rk322x-hdmi")) { + hdmi_dev->soctype = HDMI_SOC_RK322X; } else { pr_err("It is not a valid rockchip soc!"); return -ENOMEM; } - if (hdmi_dev->soctype == HDMI_SOC_RK3228) { - val = of_get_named_gpio(np, "rockchip,hotplug", 0); - if (gpio_is_valid(val) && - !devm_gpio_request_one(hdmi_dev->dev, val, - GPIOF_DIR_IN, "hotplug")) { - hdmi_dev->hpd_gpio = val; - } else { - pr_err("HDMI: invalid hotplug gpio\n"); - return -ENXIO; - } - } - if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val)) rk_hdmi_property.videosrc = val; @@ -441,9 +463,30 @@ static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev) pr_info("hdmi phy_table not exist\n"); } + of_property_read_string(np, "rockchip,vendor", + &(hdmi_dev->vendor_name)); + of_property_read_string(np, "rockchip,product", + &(hdmi_dev->product_name)); + if (!of_property_read_u32(np, "rockchip,deviceinfo", &val)) + hdmi_dev->deviceinfo = val & 0xff; + #ifdef CONFIG_MFD_SYSCON hdmi_dev->grf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); + if (IS_ERR(hdmi_dev->grf_base)) { + hdmi_dev->grf_base = NULL; + } else { + if (of_property_read_u32(np, "rockchip,grf_reg_offset", + &hdmi_dev->grf_reg_offset)) { + pr_err("get cru_reg_offset failed\n"); + return -ENXIO; + } + if (of_property_read_u32(np, "rockchip,grf_reg_shift", + &hdmi_dev->grf_reg_shift)) { + pr_err("get cru_reg_shift failed\n"); + return -ENXIO; + } + } #endif return 0; } @@ -481,7 +524,7 @@ static int rockchip_hdmiv2_probe(struct platform_device *pdev) "cannot ioremap registers,err=%d\n", ret); goto failed; } - if (hdmi_dev->soctype == HDMI_SOC_RK3228) { + if (hdmi_dev->soctype == HDMI_SOC_RK322X) { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) { dev_err(&pdev->dev, @@ -497,6 +540,15 @@ static int rockchip_hdmiv2_probe(struct platform_device *pdev) goto failed; } } + + hdmi_dev->reset = devm_reset_control_get(&pdev->dev, "hdmi"); + if (IS_ERR(hdmi_dev->reset) && + hdmi_dev->soctype != HDMI_SOC_RK3288) { + ret = PTR_ERR(hdmi_dev->reset); + dev_err(&pdev->dev, "failed to get hdmi reset: %d\n", ret); + goto failed; + } + /*enable pd and pclk and hdcp_clk*/ if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) { ret = -ENXIO; @@ -526,14 +578,17 @@ static int rockchip_hdmiv2_probe(struct platform_device *pdev) SUPPORT_YUV420 | SUPPORT_YCBCR_INPUT | SUPPORT_VESA_DMT; - } else if (hdmi_dev->soctype == HDMI_SOC_RK3228) { + } else if (hdmi_dev->soctype == HDMI_SOC_RK322X) { rk_hdmi_property.feature |= SUPPORT_4K | SUPPORT_4K_4096 | - SUPPORT_YUV420 | SUPPORT_YCBCR_INPUT | SUPPORT_1080I | SUPPORT_480I_576I; + if (rockchip_get_cpu_version()) + rk_hdmi_property.feature |= + SUPPORT_YUV420 | + SUPPORT_DEEP_10BIT; } else { ret = -ENXIO; goto failed1; @@ -566,7 +621,6 @@ static int rockchip_hdmiv2_probe(struct platform_device *pdev) hdmi_dev, &hdmi_regs_phy_fops); } #endif - rk_display_device_enable(hdmi_dev->hdmi->ddev); #ifndef HDMI_INT_USE_POLL /* get and request the IRQ */ @@ -589,20 +643,6 @@ static int rockchip_hdmiv2_probe(struct platform_device *pdev) ret); goto failed1; } - - if (hdmi_dev->soctype == HDMI_SOC_RK3228) { - hdmi_dev->irq_hpd = gpio_to_irq(hdmi_dev->hpd_gpio); - ret = devm_request_irq(hdmi_dev->dev, hdmi_dev->irq, - rockchip_hdmiv2_gpio_hpd_irq, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, - dev_name(hdmi_dev->dev), hdmi_dev); - if (ret) { - dev_err(hdmi_dev->dev, - "hdmi request hpd irq failed (%d).\n", ret); - goto failed1; - } - } #else hdmi_dev->workqueue = create_singlethread_workqueue("rockchip hdmiv2 irq"); @@ -611,6 +651,7 @@ static int rockchip_hdmiv2_probe(struct platform_device *pdev) rockchip_hdmiv2_irq_work_func(NULL); #endif + rk_display_device_enable(hdmi_dev->hdmi->ddev); dev_info(&pdev->dev, "rockchip hdmiv2 probe sucess.\n"); return 0; @@ -624,6 +665,31 @@ failed: return ret; } +static int rockchip_hdmiv2_suspend(struct platform_device *pdev, + pm_message_t state) +{ + if (hdmi_dev && + hdmi_dev->grf_base && + hdmi_dev->soctype == HDMI_SOC_RK322X) { + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_PLL_POWER_DOWN); + } + return 0; +} + +static int rockchip_hdmiv2_resume(struct platform_device *pdev) +{ + if (hdmi_dev && + hdmi_dev->grf_base && + hdmi_dev->soctype == HDMI_SOC_RK322X) { + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_PLL_POWER_UP); + } + return 0; +} + static int rockchip_hdmiv2_remove(struct platform_device *pdev) { dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n"); @@ -655,7 +721,9 @@ static struct platform_driver rockchip_hdmiv2_driver = { .of_match_table = of_match_ptr(rk_hdmi_dt_ids), #endif }, - .shutdown = rockchip_hdmiv2_shutdown, + .suspend = rockchip_hdmiv2_suspend, + .resume = rockchip_hdmiv2_resume, + .shutdown = rockchip_hdmiv2_shutdown, }; static int __init rockchip_hdmiv2_init(void) diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h index 64573fe8382b..77f2c9da35f0 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h @@ -1,7 +1,8 @@ #ifndef __RK32_HDMI_H__ #define __RK32_HDMI_H__ -#include #include +#include +#include #ifdef CONFIG_HAS_EARLYSUSPEND #include #endif @@ -28,11 +29,14 @@ struct hdmi_dev { void __iomem *regbase; void __iomem *phybase; struct regmap *grf_base; - + int grf_reg_offset; + int grf_reg_shift; + struct reset_control *reset; struct clk *pd; struct clk *pclk; struct clk *hdcp_clk; struct clk *cec_clk; + struct clk *pclk_phy; struct hdmi *hdmi; struct device *dev; struct dentry *debugfs_dir; @@ -66,8 +70,11 @@ struct hdmi_dev { struct hdmi_dev_phy_para *phy_table; int phy_table_size; - - int hpd_gpio; - int irq_hpd; + const char *vendor_name; + const char *product_name; + unsigned char deviceinfo; }; + +void ext_pll_set_27m_out(void); + #endif /*__RK32_HDMI_H__*/ diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c index b35526e40adc..c51e42ddd0b0 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_cec.c @@ -110,6 +110,15 @@ void rockchip_hdmiv2_cec_init(struct hdmi *hdmi) init = 0; /* init_waitqueue_head(&wait); */ } + /* + * Enable sending all message even if sink refuse + * message broadcasted by us. + */ + if (hdmi_dev->grf_base) + regmap_write(hdmi_dev->grf_base, + hdmi_dev->grf_reg_offset, + (1 << hdmi_dev->grf_reg_shift) | + (1 << (hdmi_dev->grf_reg_shift + 16))); hdmi_writel(hdmi_dev, IH_MUTE_CEC_STAT0, m_ERR_INITIATOR | m_ARB_LOST | m_NACK | m_DONE); CECDBG("%s", __func__); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c index 83fc1ab5a4e5..b6d989e21712 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hdcp.c @@ -392,10 +392,9 @@ static void hdcp_load_keys_cb(const struct firmware *fw, return; } hdcp->seeds = kmalloc(HDCP_KEY_SEED_SIZE, GFP_KERNEL); - if (hdcp->seeds == NULL) { - pr_err("HDCP: can't allocated space for seed keys\n"); + if (!hdcp->seeds) return; - } + memcpy(hdcp->seeds, fw->data + HDCP_KEY_SIZE, HDCP_KEY_SEED_SIZE); } diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c index 39ce9c434109..8d96fc75a0de 100755 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c @@ -1,16 +1,19 @@ +#include #include #include +#include #include #include #include "rockchip_hdmiv2.h" #include "rockchip_hdmiv2_hw.h" static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = { - /*tmdsclk = (pixclk / ref_cntrl ) * (fbdiv2 * fbdiv1) / nctrl / tmdsmhl - opmode: 0:HDMI1.4 1:HDMI2.0 - */ -/* |pixclock| tmdsclock|pixrepet|colordepth|prepdiv|tmdsmhl|opmode| - fbdiv2|fbdiv1|ref_cntrl|nctrl|propctrl|intctrl|gmpctrl| */ +/* tmdsclk = (pixclk / ref_cntrl ) * (fbdiv2 * fbdiv1) / nctrl / tmdsmhl + * opmode: 0:HDMI1.4 1:HDMI2.0 + * + * |pixclock| tmdsclock|pixrepet|colordepth|prepdiv|tmdsmhl|opmode| + * fbdiv2|fbdiv1|ref_cntrl|nctrl|propctrl|intctrl|gmpctrl| + */ {27000000, 27000000, 0, 8, 0, 0, 0, 2, 3, 0, 3, 3, 0, 0}, {27000000, 33750000, 0, 10, 1, 0, 0, @@ -29,8 +32,6 @@ static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = { 1, 3, 0, 1, 7, 0, 2}, {65000000, 65000000, 0, 8, 0, 0, 0, 1, 3, 0, 2, 5, 0, 1}, -/* {74250000, 74250000, 0, 8, 0, 0, 0, - 1, 3, 0, 2, 5, 0, 1}, */ {74250000, 74250000, 0, 8, 0, 0, 0, 4, 3, 3, 2, 7, 0, 3}, {74250000, 92812500, 0, 10, 1, 0, 0, @@ -69,8 +70,6 @@ static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = { 1, 2, 0, 1, 7, 0, 3}, {297000000, 594000000, 0, 16, 3, 3, 1, 1, 3, 1, 0, 0, 0, 3}, -/* {594000000, 297000000, 0, 8, 0, 0, 0, - 1, 3, 3, 1, 0, 0, 3},*/ {594000000, 297000000, 0, 8, 0, 0, 0, 1, 0, 1, 0, 0, 0, 3}, {594000000, 371250000, 0, 10, 1, 3, 1, @@ -84,30 +83,45 @@ static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = { }; static const struct ext_pll_config_tab EXT_PLL_TABLE[] = { - {27000000, 27000000, 8, 1, 45, 3, 1, - 1, 1, 3, 3, 4, 0}, - {27000000, 33750000, 10, 1, 45, 0, 3, - 3, 1, 3, 3, 4, 0}, - {59400000, 59400000, 8, 2, 99, 3, 1, - 1, 1, 3, 2, 2, 0}, - {59400000, 74250000, 10, 2, 99, 1, 1, - 1, 1, 3, 2, 2, 0}, - {74250000, 74250000, 8, 2, 99, 1, 1, - 1, 1, 2, 2, 2, 0}, + {27000000, 27000000, 8, 1, 90, 3, 2, + 2, 10, 3, 3, 4, 0, 1, 40, + 8}, + {27000000, 33750000, 10, 1, 90, 1, 3, + 3, 10, 3, 3, 4, 0, 1, 40, + 8}, + {59400000, 59400000, 8, 1, 99, 3, 2, + 2, 1, 3, 3, 4, 0, 1, 40, + 8}, + {59400000, 74250000, 10, 1, 99, 1, 2, + 2, 1, 3, 3, 4, 0, 1, 40, + 8}, + {74250000, 74250000, 8, 1, 99, 1, 2, + 2, 1, 2, 3, 4, 0, 1, 40, + 8}, {74250000, 92812500, 10, 4, 495, 1, 2, - 2, 1, 3, 3, 4, 0}, - {148500000, 148500000, 8, 2, 99, 1, 0, - 0, 1, 2, 1, 1, 0}, + 2, 1, 3, 3, 4, 0, 2, 40, + 4}, + {148500000, 148500000, 8, 1, 99, 1, 1, + 1, 1, 2, 2, 2, 0, 2, 40, + 4}, {148500000, 185625000, 10, 4, 495, 0, 2, - 2, 1, 3, 2, 2, 0}, - {297000000, 297000000, 8, 2, 99, 0, 0, - 0, 1, 0, 1, 1, 0}, + 2, 1, 3, 2, 2, 0, 4, 40, + 2}, + {297000000, 297000000, 8, 1, 99, 0, 1, + 1, 1, 0, 2, 2, 0, 4, 40, + 2}, {297000000, 371250000, 10, 4, 495, 1, 2, - 0, 1, 3, 1, 1, 0}, + 0, 1, 3, 1, 1, 0, 8, 40, + 1}, {594000000, 297000000, 8, 1, 99, 0, 1, - 1, 1, 0, 2, 1, 0}, + 1, 1, 0, 2, 1, 0, 4, 40, + 2}, {594000000, 371250000, 10, 4, 495, 1, 2, - 0, 1, 3, 1, 1, 1}, + 0, 1, 3, 1, 1, 1, 8, 40, + 1}, + {594000000, 594000000, 8, 1, 99, 0, 2, + 0, 1, 0, 1, 1, 0, 8, 40, + 1}, }; /* ddc i2c master reset */ @@ -200,7 +214,7 @@ static int rockchip_hdmiv2_i2cm_read_data(struct hdmi_dev *hdmi_dev, u8 offset) static void rockchip_hdmiv2_i2cm_mask_int(struct hdmi_dev *hdmi_dev, int mask) { - if (0 == mask) { + if (!mask) { hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0)); hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, @@ -343,7 +357,7 @@ static int rockchip_hdmiv2_scrambling_enable(struct hdmi_dev *hdmi_dev, int enable) { HDMIDBG("%s enable %d\n", __func__, enable); - if (1 == enable) { + if (enable == 1) { /* Write on Rx the bit Scrambling_Enable, register 0x20 */ rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 1, SCDC_TMDS_CONFIG); /* TMDS software reset request */ @@ -407,7 +421,7 @@ static const struct phy_mpll_config_tab *get_phy_mpll_tab( static void rockchip_hdmiv2_powerdown(struct hdmi_dev *hdmi_dev) { hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(1)); - if (hdmi_dev->soctype != HDMI_SOC_RK3228) { + if (hdmi_dev->soctype != HDMI_SOC_RK322X) { hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG | m_SVSRET_SIG, @@ -415,23 +429,11 @@ static void rockchip_hdmiv2_powerdown(struct hdmi_dev *hdmi_dev) v_ENHPD_RXSENSE_SIG(1)) | v_SVSRET_SIG(0); } else { hdmi_msk_reg(hdmi_dev, PHY_CONF0, - m_PDDQ_SIG, v_PDDQ_SIG(0)); - /* PHY PLL VCO is 1080MHz, output pclk is 27MHz*/ - rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_PLL_PRE_DIVIDER, - 1); - rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_PLL_FB_DIVIDER, - 45); - rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_PCLK_DIVIDER1, - 0x61); - rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_PCLK_DIVIDER2, - 0x64); - rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_TMDSCLK_DIVIDER, - 0x1d); + m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG, + v_TXPWRON_SIG(0) | v_ENHPD_RXSENSE_SIG(0)); + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_PLL_PDATA_DEN); } hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f); } @@ -464,12 +466,12 @@ int rockchip_hdmiv2_write_phy(struct hdmi_dev *hdmi_dev, break; } - if (op_status & m_I2CMPHY_DONE) - return 0; - else + if (!(op_status & m_I2CMPHY_DONE)) dev_err(hdmi_dev->hdmi->dev, "[%s] operation error,trytime=%d\n", __func__, trytime); + else + return 0; msleep(100); } @@ -503,16 +505,16 @@ int rockchip_hdmiv2_read_phy(struct hdmi_dev *hdmi_dev, break; } - if (op_status & m_I2CMPHY_DONE) { + if (!(op_status & m_I2CMPHY_DONE)) { + pr_err("[%s] operation error,trytime=%d\n", + __func__, trytime); + } else { val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1); val = (val & 0xff) << 8; val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff); pr_debug("phy_reg0x%02x: 0x%04x", reg_addr, val); return val; - } else { - pr_err("[%s] operation error,trytime=%d\n", - __func__, trytime); } msleep(100); } @@ -520,11 +522,18 @@ int rockchip_hdmiv2_read_phy(struct hdmi_dev *hdmi_dev, return -1; } -static int rk3228_set_phy(struct hdmi_dev *hdmi_dev) +#define PHY_TIMEOUT 10000 + +static int ext_phy_config(struct hdmi_dev *hdmi_dev) { - int stat = 0, i = 0; + int stat = 0, i = 0, temp; const struct ext_pll_config_tab *phy_ext = NULL; + if (hdmi_dev->grf_base) + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_PLL_POWER_DOWN | + RK322X_PLL_PDATA_DEN); if (hdmi_dev->tmdsclk_ratio_change && hdmi_dev->hdmi->edid.scdc_present == 1) rockchip_hdmiv2_scdc_set_tmds_rate(hdmi_dev); @@ -555,26 +564,54 @@ static int rk3228_set_phy(struct hdmi_dev *hdmi_dev) (phy_ext->tmsd_divider_b & 3); rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TMDSCLK_DIVIDER, stat); + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PPLL_FB_DIVIDER, + phy_ext->ppll_nf); + + if (phy_ext->ppll_no == 1) { + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PPLL_POST_DIVIDER, + 0); + stat = 0x20 | phy_ext->ppll_nd; + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PPLL_PRE_DIVIDER, + stat); + } else { + stat = ((phy_ext->ppll_no / 2) - 1) << 4; + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PPLL_POST_DIVIDER, + stat); + stat = 0xe0 | phy_ext->ppll_nd; + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_PPLL_PRE_DIVIDER, + stat); + } } else { pr_err("%s no supported phy configuration.\n", __func__); return -1; } if (hdmi_dev->phy_table) { - for (i = 0; i < hdmi_dev->phy_table_size; i++) - if (hdmi_dev->tmdsclk <= hdmi_dev->phy_table[i].maxfreq) + for (i = 0; i < hdmi_dev->phy_table_size; i++) { + temp = hdmi_dev->phy_table[i].maxfreq; + if (hdmi_dev->tmdsclk <= temp) break; + } } if (i != hdmi_dev->phy_table_size) { - rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_SIGNAL_CTRL, 0xff); - stat = ((hdmi_dev->phy_table[i].slopeboost & 3) << 6) | - ((hdmi_dev->phy_table[i].slopeboost & 3) << 4) | - ((hdmi_dev->phy_table[i].slopeboost & 3) << 2) | - (hdmi_dev->phy_table[i].slopeboost & 3); - rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_SLOPEBOOST, stat); + if (hdmi_dev->phy_table[i].slopeboost) { + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_SIGNAL_CTRL, 0xff); + temp = hdmi_dev->phy_table[i].slopeboost - 1; + stat = ((temp & 3) << 6) | ((temp & 3) << 4) | + ((temp & 3) << 2) | (temp & 3); + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_SLOPEBOOST, stat); + } else { + rockchip_hdmiv2_write_phy(hdmi_dev, + EXT_PHY_SIGNAL_CTRL, 0x0f); + } stat = ((hdmi_dev->phy_table[i].pre_emphasis & 3) << 4) | ((hdmi_dev->phy_table[i].pre_emphasis & 3) << 2) | (hdmi_dev->phy_table[i].pre_emphasis & 3); @@ -590,12 +627,64 @@ static int rk3228_set_phy(struct hdmi_dev *hdmi_dev) EXT_PHY_LEVEL2, stat); } else { rockchip_hdmiv2_write_phy(hdmi_dev, - EXT_PHY_SIGNAL_CTRL, 0); + EXT_PHY_SIGNAL_CTRL, 0x0f); } + rockchip_hdmiv2_write_phy(hdmi_dev, 0xf3, 0x22); + + stat = clk_get_rate(hdmi_dev->pclk_phy) / 100000; + rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL, + ((stat >> 8) & 0xff) | 0x80); + rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL_DIV_L, + stat & 0xff); + if (hdmi_dev->tmdsclk > 340000000) + stat = EXT_PHY_AUTO_R100_OHMS; + else if (hdmi_dev->tmdsclk > 200000000) + stat = EXT_PHY_AUTO_R50_OHMS; + else + stat = EXT_PHY_AUTO_ROPEN_CIRCUIT; + rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_RESIS_AUTO, + stat | 0x20); + rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL, + (stat >> 8) & 0xff); + if (hdmi_dev->tmdsclk > 200000000) + stat = 0; + else + stat = 0x11; + rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_PLL_BW, stat); + rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_PPLL_BW, 0x27); + if (hdmi_dev->grf_base) + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_PLL_POWER_UP); if (hdmi_dev->tmdsclk_ratio_change) msleep(100); + else + usleep_range(900, 1000); hdmi_msk_reg(hdmi_dev, PHY_CONF0, - m_PDDQ_SIG, v_PDDQ_SIG(1)); + m_TXPWRON_SIG, v_TXPWRON_SIG(1)); + i = 0; + while (i++ < PHY_TIMEOUT) { + if ((i % 10) == 0) { + temp = EXT_PHY_PPLL_POST_DIVIDER; + stat = rockchip_hdmiv2_read_phy(hdmi_dev, temp); + if (stat & EXT_PHY_PPLL_LOCK_STATUS_MASK) + break; + usleep_range(1000, 2000); + } + } + if ((stat & EXT_PHY_PPLL_LOCK_STATUS_MASK) == 0) { + stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK); + dev_err(hdmi_dev->hdmi->dev, + "PHY PLL not locked: PCLK_ON=%d,TMDSCLK_ON=%d\n", + (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5); + return -1; + } + + if (hdmi_dev->grf_base) + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_PLL_PDATA_EN); + return 0; } @@ -604,8 +693,8 @@ static int rockchip_hdmiv2_config_phy(struct hdmi_dev *hdmi_dev) int stat = 0, i = 0; const struct phy_mpll_config_tab *phy_mpll = NULL; - if (hdmi_dev->soctype == HDMI_SOC_RK3228) - return rk3228_set_phy(hdmi_dev); + if (hdmi_dev->soctype == HDMI_SOC_RK322X) + return ext_phy_config(hdmi_dev); hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV, m_PHY_I2CM_FAST_STD, v_PHY_I2CM_FAST_STD(0)); @@ -701,14 +790,9 @@ static int rockchip_hdmiv2_config_phy(struct hdmi_dev *hdmi_dev) msleep(100); /* power on PHY */ hdmi_writel(hdmi_dev, PHY_CONF0, 0x2e); - /* - hdmi_msk_reg(hdmi_dev, PHY_CONF0, - m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG, - v_PDDQ_SIG(0) | v_TXPWRON_SIG(1) | - v_ENHPD_RXSENSE_SIG(1)); - */ + /* check if the PHY PLL is locked */ - #define PHY_TIMEOUT 10000 + i = 0; while (i++ < PHY_TIMEOUT) { if ((i % 10) == 0) { @@ -761,24 +845,36 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv, tmdsclk = 2 * mode->pixclock; else tmdsclk = mode->pixclock; - switch (vpara->color_output_depth) { - case 10: - tmdsclk += tmdsclk / 4; - break; - case 12: - tmdsclk += tmdsclk / 2; - break; - case 16: - tmdsclk += tmdsclk; - break; - case 8: - default: - break; + if (vpara->color_output != HDMI_COLOR_YCBCR422) { + switch (vpara->color_output_depth) { + case 10: + tmdsclk += tmdsclk / 4; + break; + case 12: + tmdsclk += tmdsclk / 2; + break; + case 16: + tmdsclk += tmdsclk; + break; + case 8: + default: + break; + } + } else if (vpara->color_output_depth > 12) { + /* YCbCr422 mode only support up to 12bit */ + vpara->color_output_depth = 12; } - - if (tmdsclk > 594000000) { + if ((tmdsclk > 594000000) || + (tmdsclk > 340000000 && + tmdsclk > hdmi_drv->edid.maxtmdsclock)) { + pr_warn("out of max tmds clock, limit to 8bit\n"); vpara->color_output_depth = 8; - tmdsclk = mode->pixclock; + if (vpara->color_input == HDMI_COLOR_YCBCR420) + tmdsclk = mode->pixclock / 2; + else if (vpara->format_3d != HDMI_3D_FRAME_PACKING) + tmdsclk = mode->pixclock; + else + return -1; } if ((tmdsclk > 340000000) || @@ -793,8 +889,13 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv, else hdmi_dev->pixelclk = mode->pixclock; hdmi_dev->pixelrepeat = timing->pixelrepeat; - hdmi_dev->colordepth = vpara->color_output_depth; - + /* hdmi_dev->colordepth is used for find pll config. + * For YCbCr422, tmdsclk is same on all color depth. + */ + if (vpara->color_output == HDMI_COLOR_YCBCR422) + hdmi_dev->colordepth = 8; + else + hdmi_dev->colordepth = vpara->color_output_depth; pr_info("pixel clk is %lu tmds clk is %u\n", hdmi_dev->pixelclk, hdmi_dev->tmdsclk); /* Start/stop HDCP keepout window generation */ @@ -891,8 +992,9 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv, value = mode->vsync_len; hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (value & 0xff)); - /*Set the control period minimum duration - (min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)*/ + /* Set the control period minimum duration (min. of 12 pixel + * clock cycles, refer to HDMI 1.4b specification) + */ hdmi_writel(hdmi_dev, FC_CTRLDUR, 12); hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32); @@ -901,10 +1003,11 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv, */ hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, (hdmi_dev->tmdsclk/1000) * 50 / (256 * 512)); +#if 0 if (!hdmi_drv->uboot) hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ, m_TMDS_SWRST, v_TMDS_SWRST(0)); -#if 0 + /*Set PreambleFilter*/ for (i = 0; i < 3; i++) { value = (i + 1) * 11; @@ -917,7 +1020,9 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv, } #endif - hdmi_writel(hdmi_dev, FC_PRCONF, v_FC_PR_FACTOR(timing->pixelrepeat)); + hdmi_writel(hdmi_dev, FC_PRCONF, + v_FC_PR_FACTOR(timing->pixelrepeat) | + v_FC_PR_FACTOR_OUT(timing->pixelrepeat - 1)); return 0; } @@ -925,7 +1030,7 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv, static int rockchip_hdmiv2_video_packetizer(struct hdmi_dev *hdmi_dev, struct hdmi_video *vpara) { - unsigned char color_depth = 0; + unsigned char color_depth = COLOR_DEPTH_24BIT_DEFAULT; unsigned char output_select = 0; unsigned char remap_size = 0; @@ -969,12 +1074,10 @@ static int rockchip_hdmiv2_video_packetizer(struct hdmi_dev *hdmi_dev, output_select = OUT_FROM_8BIT_BYPASS; break; } - - /*Config Color Depth*/ - hdmi_msk_reg(hdmi_dev, VP_PR_CD, - m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth)); } - + /*Config Color Depth*/ + hdmi_msk_reg(hdmi_dev, VP_PR_CD, + m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth)); /*Config pixel repettion*/ hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR, v_DESIRED_PR_FACTOR(hdmi_dev->pixelrepeat - 1)); @@ -1078,7 +1181,8 @@ static int rockchip_hdmiv2_video_sampler(struct hdmi_dev *hdmi_dev, } /* Set Data enable signal from external - and set video sample input mapping */ + * and set video sample input mapping + */ hdmi_msk_reg(hdmi_dev, TX_INVID0, m_INTERNAL_DE_GEN | m_VIDEO_MAPPING, v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code)); @@ -1102,9 +1206,10 @@ static int rockchip_hdmiv2_video_sampler(struct hdmi_dev *hdmi_dev, static const char coeff_csc[][24] = { /* G R B Bias - A1 | A2 | A3 | A4 | - B1 | B2 | B3 | B4 | - C1 | C2 | C3 | C4 | */ + * A1 | A2 | A3 | A4 | + * B1 | B2 | B3 | B4 | + * C1 | C2 | C3 | C4 | + */ { /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */ 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /*G*/ 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x00, 0x40, /*R*/ @@ -1257,16 +1362,10 @@ static int hdmi_dev_detect_hotplug(struct hdmi *hdmi) struct hdmi_dev *hdmi_dev = hdmi->property->priv; u32 value; - if (hdmi_dev->soctype == HDMI_SOC_RK3228) { - value = gpio_get_value(hdmi_dev->hpd_gpio); - if (value) - return HDMI_HPD_ACTIVED; - } else { - value = hdmi_readl(hdmi_dev, PHY_STAT0) - HDMIDBG("[%s] reg%x value %02x\n", __func__, PHY_STAT0, value); - if (value & m_PHY_HPD) - return HDMI_HPD_ACTIVED; - } + value = hdmi_readl(hdmi_dev, PHY_STAT0); + HDMIDBG("[%s] reg%x value %02x\n", __func__, PHY_STAT0, value); + if (value & m_PHY_HPD) + return HDMI_HPD_ACTIVED; return HDMI_HPD_REMOVED; } @@ -1465,15 +1564,44 @@ static int hdmi_dev_config_vsi(struct hdmi *hdmi, for (i = 0; i < 3; i++) hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]); hdmi_writel(hdmi_dev, FC_VSDSIZE, 0x6); -/* if (auto_send) { */ + hdmi_writel(hdmi_dev, FC_DATAUTO1, 0); hdmi_writel(hdmi_dev, FC_DATAUTO2, 0x11); hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(1)); -/* } - else { - hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1)); + return 0; +} + +static int hdmi_dev_config_spd(struct hdmi *hdmi, const char *vendor, + const char *product, char deviceinfo) +{ + struct hdmi_dev *hdmi_dev; + int i, len; + + if (!hdmi || !vendor || !product) + return -1; + hdmi_dev = hdmi->property->priv; + + hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_SPD_AUTO, v_SPD_AUTO(0)); + len = strlen(vendor); + for (i = 0; i < 8; i++) { + if (i < len) + hdmi_writel(hdmi_dev, FC_SPDVENDORNAME0 + i, + vendor[i]); + else + hdmi_writel(hdmi_dev, FC_SPDVENDORNAME0 + i, + 0); + } + len = strlen(product); + for (i = 0; i < 16; i++) { + if (i < len) + hdmi_writel(hdmi_dev, FC_SPDPRODUCTNAME0 + i, + product[i]); + else + hdmi_writel(hdmi_dev, FC_SPDPRODUCTNAME0 + i, + 0); } -*/ + hdmi_writel(hdmi_dev, FC_SPDDEVICEINF, deviceinfo); + hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_SPD_AUTO, v_SPD_AUTO(1)); return 0; } @@ -1490,13 +1618,18 @@ static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara) if (!hdmi->uboot) { /* befor configure video, we power off phy */ - if (hdmi_dev->soctype != HDMI_SOC_RK3228) + if (hdmi_dev->soctype != HDMI_SOC_RK322X) { hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_PDDQ_SIG | m_TXPWRON_SIG, v_PDDQ_SIG(1) | v_TXPWRON_SIG(0)); - else + } else { hdmi_msk_reg(hdmi_dev, PHY_CONF0, - m_PDDQ_SIG, v_PDDQ_SIG(0)); + m_ENHPD_RXSENSE_SIG, + v_ENHPD_RXSENSE_SIG(1)); + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_PLL_POWER_DOWN); + } /* force output blue */ if (vpara->color_output == HDMI_COLOR_RGB_0_255) { hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/ @@ -1507,9 +1640,9 @@ static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara) hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/ hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x10); /*B*/ } else { - hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x80); /*R*/ - hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/ - hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x80); /*B*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x80); /*Cr*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*Y*/ + hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x80); /*Cb*/ } hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1)); @@ -1529,6 +1662,9 @@ static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara) if (vpara->sink_hdmi == OUTPUT_HDMI) { hdmi_dev_config_avi(hdmi_dev, vpara); + hdmi_dev_config_spd(hdmi, hdmi_dev->vendor_name, + hdmi_dev->product_name, + hdmi_dev->deviceinfo); if (vpara->format_3d != HDMI_3D_NONE) { hdmi_dev_config_vsi(hdmi, vpara->format_3d, @@ -1560,23 +1696,25 @@ static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara) static void hdmi_dev_config_aai(struct hdmi_dev *hdmi_dev, struct hdmi_audio *audio) { - /*Refer to CEA861-E Audio infoFrame*/ - /*Set both Audio Channel Count and Audio Coding - Type Refer to Stream Head for HDMI*/ + /* Refer to CEA861-E Audio infoFrame + * Set both Audio Channel Count and Audio Coding + * Type Refer to Stream Head for HDMI + */ hdmi_msk_reg(hdmi_dev, FC_AUDICONF0, m_FC_CHN_CNT | m_FC_CODING_TYEP, v_FC_CHN_CNT(audio->channel-1) | v_FC_CODING_TYEP(0)); - /*Set both Audio Sample Size and Sample Frequency - Refer to Stream Head for HDMI*/ + /* Set both Audio Sample Size and Sample Frequency + * Refer to Stream Head for HDMI + */ hdmi_msk_reg(hdmi_dev, FC_AUDICONF1, m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ, v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0)); - /*Set Channel Allocation*/ + /* Set Channel Allocation */ hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00); - /*Set LFEPBL¡¢DOWN-MIX INH and LSV*/ + /* Set LFEPBLDOWN-MIX INH and LSV */ hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00); } @@ -1735,12 +1873,12 @@ static int hdmi_dev_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio) hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7); hdmi_writel(hdmi_dev, AUD_CONF2, 0x0); usleep_range(90, 100); - if (I2S_CHANNEL_7_8 == channel) { + if (channel == I2S_CHANNEL_7_8) { HDMIDBG("hbr mode.\n"); hdmi_writel(hdmi_dev, AUD_CONF2, 0x1); word_length = I2S_24BIT_SAMPLE; - } else if ((HDMI_AUDIO_FS_48000 == audio->rate) || - (HDMI_AUDIO_FS_192000 == audio->rate)) { + } else if ((audio->rate == HDMI_AUDIO_FS_48000) || + (audio->rate == HDMI_AUDIO_FS_192000)) { HDMIDBG("nlpcm mode.\n"); hdmi_writel(hdmi_dev, AUD_CONF2, 0x2); word_length = I2S_24BIT_SAMPLE; @@ -1818,20 +1956,16 @@ static int hdmi_dev_control_output(struct hdmi *hdmi, int enable) } } /* if (enable & HDMI_AUDIO_MUTE) { - hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, - m_AUD_PACK_SAMPFIT, - v_AUD_PACK_SAMPFIT(0x0F)); - } -*/ if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) { + * hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, + * m_AUD_PACK_SAMPFIT, + * v_AUD_PACK_SAMPFIT(0x0F)); + * } + */ + if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) { if (hdmi->ops->hdcp_power_off_cb) hdmi->ops->hdcp_power_off_cb(hdmi); rockchip_hdmiv2_powerdown(hdmi_dev); -/* - hdmi_msk_reg(hdmi_dev, PHY_CONF0, - m_PDDQ_SIG | m_TXPWRON_SIG, - v_PDDQ_SIG(1) | v_TXPWRON_SIG(0)); - hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f); -*/ } + } } return 0; } @@ -1904,22 +2038,29 @@ void rockchip_hdmiv2_dev_initial(struct hdmi_dev *hdmi_dev) struct hdmi *hdmi = hdmi_dev->hdmi; if (!hdmi->uboot) { - /* reset hdmi */ + pr_info("reset hdmi\n"); if (hdmi_dev->soctype == HDMI_SOC_RK3288) { - writel_relaxed((1 << 9) | (1 << 25), - RK_CRU_VIRT + 0x01d4); - udelay(1); - writel_relaxed((0 << 9) | (1 << 25), - RK_CRU_VIRT + 0x01d4); - } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) { - pr_info("reset hdmi\n"); - regmap_write(hdmi_dev->grf_base, 0x031c, - (1 << 9) | (1 << 25)); - udelay(5); - regmap_write(hdmi_dev->grf_base, 0x031c, - (0 << 9) | (1 << 25)); + rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HDMI, true); + usleep_range(10, 20); + rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HDMI, false); + } else { + if (hdmi_dev->soctype == HDMI_SOC_RK322X) { + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON2, + RK322X_DDC_MASK_EN); + regmap_write(hdmi_dev->grf_base, + RK322X_GRF_SOC_CON6, + RK322X_IO_3V_DOMAIN); + } + reset_control_assert(hdmi_dev->reset); + usleep_range(10, 20); + reset_control_deassert(hdmi_dev->reset); } rockchip_hdmiv2_powerdown(hdmi_dev); + } else { + hdmi->hotplug = hdmi_dev_detect_hotplug(hdmi); + if (hdmi->hotplug != HDMI_HPD_ACTIVED) + hdmi->uboot = 0; } /*mute unnecessary interrrupt, only enable hpd*/ hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT0, 0xff); @@ -1990,7 +2131,8 @@ irqreturn_t rockchip_hdmiv2_dev_irq(int irq, void *priv) /* CEC */ if (cec_int) { hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int); - rockchip_hdmiv2_cec_isr(hdmi_dev, cec_int); + if (hdmi_dev->hdmi->property->feature & SUPPORT_CEC) + rockchip_hdmiv2_cec_isr(hdmi_dev, cec_int); } /* HDCP */ if (hdcp_int) { diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h index ee5c402f9b04..de301bf3ba7f 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.h @@ -18,43 +18,53 @@ enum { /* Color Space Convertion Mode */ enum { CSC_RGB_0_255_TO_RGB_16_235_8BIT, /* RGB 0-255 input to RGB - 16-235 output that is 8bit - clolor depth */ + * 16-235 output that is 8bit + * clolor depth + */ CSC_RGB_0_255_TO_RGB_16_235_10BIT, /* RGB 0-255 input to RGB - 16-235 output that is 8bit - clolor depth */ + * 16-235 output that is 8bit + * clolor depth + */ CSC_RGB_0_255_TO_ITU601_16_235_8BIT, /* RGB 0-255 input to YCbCr - 16-235 output according - BT601 that is 8bit clolor - depth */ + * 16-235 output according + * BT601 that is 8bit clolor + * depth + */ CSC_RGB_0_255_TO_ITU601_16_235_10BIT, /* RGB 0-255 input to YCbCr - 16-235 output according - BT601 that is 10bit clolor - depth */ + * 16-235 output according + * BT601 that is 10bit clolor + * depth + */ CSC_RGB_0_255_TO_ITU709_16_235_8BIT, /* RGB 0-255 input to YCbCr - 16-235 output accroding - BT709 that is 8bit clolor - depth */ + * 16-235 output accroding + * BT709 that is 8bit clolor + * depth + */ CSC_RGB_0_255_TO_ITU709_16_235_10BIT, /* RGB 0-255 input to YCbCr - 16-235 output accroding - BT709 that is 10bit clolor - depth */ + * 16-235 output accroding + * BT709 that is 10bit clolor + * depth + */ CSC_ITU601_16_235_TO_RGB_0_255_8BIT, /* YCbCr 16-235 input to RGB - 0-255 output according - BT601 that is 8bit clolor - depth */ + * 0-255 output according + * BT601 that is 8bit clolor + * depth + */ CSC_ITU709_16_235_TO_RGB_0_255_8BIT, /* YCbCr 16-235 input to RGB - 0-255 output according - BT709 that is 8bit clolor - depth */ + * 0-255 output according + * BT709 that is 8bit clolor + * depth + */ CSC_ITU601_16_235_TO_RGB_16_235_8BIT, /* YCbCr 16-235 input to RGB - 16-235 output according - BT601 that is 8bit clolor - depth */ + * 16-235 output according + * BT601 that is 8bit clolor + * depth + */ CSC_ITU709_16_235_TO_RGB_16_235_8BIT /* YCbCr 16-235 input to RGB - 16-235 output according - BT709 that is 8bit clolor - depth */ + * 16-235 output according + * BT709 that is 8bit clolor + * depth + */ }; #define HDMI_SCL_RATE (100*1000) @@ -688,6 +698,8 @@ enum { #define FC_PRCONF 0x10e0 #define m_FC_PR_FACTOR (0x0f << 4) #define v_FC_PR_FACTOR(n) (((n)&0x0f) << 4) +#define m_FC_PR_FACTOR_OUT (0x0f) +#define v_FC_PR_FACTOR_OUT(n) ((n) & 0x0f) #define FC_SCRAMBLER_CTRL 0x10e1 #define m_FC_SCRAMBLE_UCP (1 << 4) @@ -1526,14 +1538,20 @@ struct phy_mpll_config_tab { u16 gmp_cntrl; }; -/* PHY Defined for RK3228 */ +/* PHY Defined for RK322X */ #define EXT_PHY_CONTROL 0 #define EXT_PHY_ANALOG_RESET_MASK 0x80 #define EXT_PHY_DIGITAL_RESET_MASK 0x40 #define EXT_PHY_PCLK_INVERT_MASK 0x08 #define EXT_PHY_PREPCLK_INVERT_MASK 0x04 #define EXT_PHY_TMDSCLK_INVERT_MASK 0x02 - #define ExT_PHY_SRC_SELECT_MASK 0x01 + #define EXT_PHY_SRC_SELECT_MASK 0x01 + +#define EXT_PHY_TERM_CAL 0x03 + #define EXT_PHY_TERM_CAL_EN_MASK 0x80 + #define EXT_PHY_TERM_CAL_DIV_H_MASK 0x7f + +#define EXT_PHY_TERM_CAL_DIV_L 0x04 #define EXT_PHY_PLL_PRE_DIVIDER 0xe2 #define EXT_PHY_PLL_FB_BIT8_MASK 0x80 @@ -1555,9 +1573,11 @@ struct phy_mpll_config_tab { #define EXT_PHY_TMDSCLK_DIVIDERA_MASK 0x0c #define EXT_PHY_TMDSCLK_DIVIDERB_MASK 0x03 +#define EXT_PHY_PLL_BW 0xe7 + #define EXT_PHY_PPLL_PRE_DIVIDER 0xe9 #define EXT_PHY_PPLL_ENABLE_MASK 0xc0 - #define EXT_PHY_PPLL_PRE_DIVIDER_MASK 0x0f + #define EXT_PHY_PPLL_PRE_DIVIDER_MASK 0x1f #define EXT_PHY_PPLL_FB_DIVIDER 0xea @@ -1566,6 +1586,8 @@ struct phy_mpll_config_tab { #define EXT_PHY_PPLL_POST_DIVIDER_MASK 0x30 #define EXT_PHY_PPLL_LOCK_STATUS_MASK 0x01 +#define EXT_PHY_PPLL_BW 0xec + #define EXT_PHY_SIGNAL_CTRL 0xee #define EXT_PHY_TRANSITION_CLK_EN_MASK 0x80 #define EXT_PHY_TRANSITION_D0_EN_MASK 0x40 @@ -1595,6 +1617,24 @@ struct phy_mpll_config_tab { #define EXT_PHY_LEVEL_D1_MASK 0xf0 #define EXT_PHY_LEVEL_D0_MASK 0x0f +#define EXT_PHY_TERM_RESIS_AUTO 0xf4 + #define EXT_PHY_AUTO_R50_OHMS 0 + #define EXT_PHY_AUTO_R75_OHMS (1 << 2) + #define EXT_PHY_AUTO_R100_OHMS (2 << 2) + #define EXT_PHY_AUTO_ROPEN_CIRCUIT (3 << 2) + +#define EXT_PHY_TERM_RESIS_MANUAL_CLK 0xfb +#define EXT_PHY_TERM_RESIS_MANUAL_D2 0xfc +#define EXT_PHY_TERM_RESIS_MANUAL_D1 0xfd +#define EXT_PHY_TERM_RESIS_MANUAL_D0 0xfe + +#define RK322X_DDC_MASK_EN ((3 << 13) | (3 << (13 + 16))) +#define RK322X_IO_3V_DOMAIN ((7 << 4) | (7 << (4 + 16))) +#define RK322X_PLL_POWER_DOWN (BIT(12) | BIT(12 + 16)) +#define RK322X_PLL_POWER_UP BIT(12 + 16) +#define RK322X_PLL_PDATA_DEN BIT(11 + 16) +#define RK322X_PLL_PDATA_EN (BIT(11) | BIT(11 + 16)) + struct ext_pll_config_tab { u32 pix_clock; u32 tmdsclock; @@ -1609,6 +1649,9 @@ struct ext_pll_config_tab { u8 pclk_divider_c; u8 pclk_divider_d; u8 vco_div_5; + u8 ppll_nd; + u8 ppll_nf; + u8 ppll_no; }; /* * HDMI TX PHY Define End -- 2.34.1