hdmi:rk3288/rk3368: support 3D type Frame packing.
authorZheng Yang <zhengyang@rock-chips.com>
Thu, 30 Jul 2015 02:43:04 +0000 (10:43 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Thu, 30 Jul 2015 02:43:04 +0000 (10:43 +0800)
Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
drivers/video/rockchip/hdmi/rockchip-hdmi-core.c
drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c
drivers/video/rockchip/hdmi/rockchip-hdmiv2/rockchip_hdmiv2_hw.c

index 0b411b321c513862997654653382576318e5fca0..3afce005961520b9d44f793940d9337e7622472c 100644 (file)
@@ -100,22 +100,21 @@ static void hdmi_wq_set_video(struct hdmi *hdmi)
                } else {
                        video->color_output = hdmi->colormode;
                }
+               if (hdmi->vic & HDMI_VIDEO_YUV420) {
+                       video->color_output = HDMI_COLOR_YCBCR420;
+                       deepcolor = hdmi->edid.deepcolor_420;
+               } else {
+                       deepcolor = hdmi->edid.deepcolor;
+               }
+               if ((hdmi->property->feature & SUPPORT_DEEP_10BIT) &&
+                   (deepcolor & HDMI_DEEP_COLOR_30BITS)) {
+                       if (hdmi->colordepth == HDMI_DEPP_COLOR_AUTO ||
+                           hdmi->colordepth == 10)
+                               video->color_output_depth = 10;
+               } else {
+                       video->color_output_depth = 8;
+               }
        }
-       if (hdmi->vic & HDMI_VIDEO_YUV420) {
-               video->color_output = HDMI_COLOR_YCBCR420;
-               deepcolor = hdmi->edid.deepcolor_420;
-       } else {
-               deepcolor = hdmi->edid.deepcolor;
-       }
-       if ((hdmi->property->feature & SUPPORT_DEEP_10BIT) &&
-           (deepcolor & HDMI_DEEP_COLOR_30BITS)) {
-               if (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);
        video->color_input = HDMI_COLOR_RGB_0_255;
        if (hdmi->property->feature & SUPPORT_YCBCR_INPUT) {
@@ -396,13 +395,23 @@ static void hdmi_work_queue(struct work_struct *work)
                                           hdmi->mute & (~HDMI_AUDIO_MUTE));
                break;
        case HDMI_SET_3D:
-               if (hdmi->ops->setvsi) {
-                       if (hdmi->mode_3d != HDMI_3D_NONE)
+               if (hdmi->ops->setvsi && hdmi->edid.sink_hdmi) {
+                       if (hdmi->mode_3d == HDMI_3D_FRAME_PACKING ||
+                           hdmi->video.format_3d ==
+                           HDMI_3D_FRAME_PACKING) {
+                               hdmi_wq_set_output(hdmi,
+                                                  HDMI_VIDEO_MUTE |
+                                                  HDMI_AUDIO_MUTE);
+                               msleep(100);
+                               hdmi_wq_set_video(hdmi);
+                               hdmi_wq_set_output(hdmi, hdmi->mute);
+                       } else if (hdmi->mode_3d != HDMI_3D_NONE) {
                                hdmi->ops->setvsi(hdmi, hdmi->mode_3d,
                                                  HDMI_VIDEO_FORMAT_3D);
-                       else if ((hdmi->vic & HDMI_TYPE_MASK) == 0)
+                       } else if ((hdmi->vic & HDMI_TYPE_MASK) == 0) {
                                hdmi->ops->setvsi(hdmi, hdmi->vic,
                                                  HDMI_VIDEO_FORMAT_NORMAL);
+                       }
                }
                break;
        case HDMI_SET_COLOR:
index 9f6bf9ef320596d6645b2fd9061ee6365e0f6ae4..d25e99e7b1422982399750311224851333a91c30 100644 (file)
@@ -73,7 +73,21 @@ static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi)
        mode = (struct fb_videomode *)&(hdmi_mode[i].mode);
 
        screen->mode = *mode;
-
+       if (hdmi->video.format_3d == HDMI_3D_FRAME_PACKING) {
+               screen->mode.pixclock = 2 * mode->pixclock;
+               if (mode->vmode == 0) {
+                       screen->mode.yres = 2 * mode->yres +
+                                       mode->upper_margin +
+                                       mode->lower_margin +
+                                       mode->vsync_len;
+               } else {
+                       screen->mode.yres = 2 * mode->yres +
+                                           3 * (mode->upper_margin +
+                                                mode->lower_margin +
+                                                mode->vsync_len) + 2;
+                       screen->mode.vmode = 0;
+               }
+       }
        /* Pin polarity */
        #ifdef CONFIG_HDMI_RK616
        screen->pin_hsync = 0;
index ba94ca1e1560a4eb0431a2ac4ea0b0ca9d3f5871..46023e399233e6bc1db87df911cc917749cebb16 100755 (executable)
@@ -303,8 +303,8 @@ static const struct phy_mpll_config_tab *get_phy_mpll_tab(
 
        if (pixclock == 0)
                return NULL;
-       HDMIDBG("%s pixClock %u pixRepet %d colorDepth %d\n",
-               __func__, pixclock, pixrepet, colordepth);
+       HDMIDBG("%s pixClock %u tmdsclk %u pixRepet %d colorDepth %d\n",
+               __func__, pixclock, tmdsclk, pixrepet, colordepth);
        for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) {
                if ((PHY_MPLL_TABLE[i].pix_clock == pixclock) &&
                    (PHY_MPLL_TABLE[i].tmdsclock == tmdsclk) &&
@@ -546,6 +546,8 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
        mode = &(timing->mode);
        if (vpara->color_input == HDMI_COLOR_YCBCR420)
                tmdsclk = mode->pixclock / 2;
+       else if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
+               tmdsclk = 2 * mode->pixclock;
        else
                tmdsclk = mode->pixclock;
        switch (vpara->color_output_depth) {
@@ -567,7 +569,7 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
                vpara->color_output_depth = 8;
                tmdsclk = mode->pixclock;
        }
-       pr_info("pixel clk is %u tmds clk is %u\n", mode->pixclock, tmdsclk);
+
        if ((tmdsclk > 340000000 && hdmi_dev->tmdsclk < 340000000) ||
            (tmdsclk < 340000000 && hdmi_dev->tmdsclk > 340000000))
                hdmi_dev->tmdsclk_ratio_change = true;
@@ -575,10 +577,15 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
                hdmi_dev->tmdsclk_ratio_change = false;
 
        hdmi_dev->tmdsclk = tmdsclk;
-       hdmi_dev->pixelclk = mode->pixclock;
+       if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
+               hdmi_dev->pixelclk = 2 * mode->pixclock;
+       else
+               hdmi_dev->pixelclk = mode->pixclock;
        hdmi_dev->pixelrepeat = timing->pixelrepeat;
        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 */
        hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
                     m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1));
@@ -610,7 +617,8 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
                     v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) |
                     v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->sink_hdmi) |
                     v_FC_INTERLACE_MODE(mode->vmode));
-       if (mode->vmode == FB_VMODE_INTERLACED)
+       if (mode->vmode == FB_VMODE_INTERLACED &&
+           vpara->format_3d != HDMI_3D_FRAME_PACKING)
                hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
                             m_FC_VBLANK, v_FC_VBLANK(1));
        else
@@ -623,7 +631,20 @@ static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
        hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(value >> 8));
        hdmi_writel(hdmi_dev, FC_INHACTIV0, (value & 0xff));
 
-       value = mode->yres;
+       if (vpara->format_3d == HDMI_3D_FRAME_PACKING) {
+               if (mode->vmode == 0)
+                       value = 2 * mode->yres +
+                               mode->upper_margin +
+                               mode->lower_margin +
+                               mode->vsync_len;
+               else
+                       value = 2 * mode->yres +
+                               3 * (mode->upper_margin +
+                                    mode->lower_margin +
+                                    mode->vsync_len) + 2;
+       } else {
+               value = mode->yres;
+       }
        hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(value >> 8));
        hdmi_writel(hdmi_dev, FC_INVACTIV0, (value & 0xff));