diff options
author | Jason Chen <b02280@freescale.com> | 2009-12-17 18:58:56 +0800 |
---|---|---|
committer | Justin Waters <justin.waters@timesys.com> | 2010-03-25 14:01:48 -0400 |
commit | 3e022cac4409a2eab95bd89961b3bae12bb119d2 (patch) | |
tree | 58e9e8ae96026106be0962d0c2aafeb17ff883a8 | |
parent | 8f10592ec0561f889f203efbe4ce85a4e6474eb2 (diff) |
ENGR00119274 TVE: HDTV can not work
1.arrange display port according to choice of different display device
2.for ipu_disp.c: not round pixel clock to even for tvout.
3.cmdline "hdtv" enable 720P, "hdtv=2" enable 720P as primary.
Signed-off-by: Jason Chen <b02280@freescale.com>
-rw-r--r-- | arch/arm/mach-mx37/mx37_3stack.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx51/mx51_3stack.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-mx51/mx51_babbage.c | 91 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_disp.c | 33 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_ipuv3_fb.c | 2 | ||||
-rw-r--r-- | drivers/video/mxc/tve.c | 20 |
6 files changed, 96 insertions, 55 deletions
diff --git a/arch/arm/mach-mx37/mx37_3stack.c b/arch/arm/mach-mx37/mx37_3stack.c index ce2ff2b47f8d..c1be8aeb1983 100644 --- a/arch/arm/mach-mx37/mx37_3stack.c +++ b/arch/arm/mach-mx37/mx37_3stack.c @@ -398,8 +398,10 @@ static struct platform_device mxc_fb_device[] = { }, }; +extern int g_di1_tvout; static void mxc_init_fb(void) { + g_di1_tvout = 1; (void)platform_device_register(&mxc_fb_device[0]); (void)platform_device_register(&mxc_fb_device[1]); (void)platform_device_register(&mxc_fb_device[2]); diff --git a/arch/arm/mach-mx51/mx51_3stack.c b/arch/arm/mach-mx51/mx51_3stack.c index 39ddfbb6d0a4..8496569df78a 100644 --- a/arch/arm/mach-mx51/mx51_3stack.c +++ b/arch/arm/mach-mx51/mx51_3stack.c @@ -418,9 +418,10 @@ static struct platform_device lcd_wvga_device = { }, }; +extern int g_di1_tvout; static void mxc_init_fb(void) { - + g_di1_tvout = 1; if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) lcd_data.reset = lcd_reset_to2; diff --git a/arch/arm/mach-mx51/mx51_babbage.c b/arch/arm/mach-mx51/mx51_babbage.c index c94dbf4024c4..665c3279f210 100644 --- a/arch/arm/mach-mx51/mx51_babbage.c +++ b/arch/arm/mach-mx51/mx51_babbage.c @@ -98,11 +98,12 @@ static struct cpu_wp cpu_wp_auto[] = { static struct fb_videomode video_modes[] = { { /* 720p60 TV output */ - "720P60", 60, 1280, 720, 7418, - 220, 110, - 20, 5, - 40, 5, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_EXT, + "720P60", 60, 1280, 720, 13468, + 260, 109, + 25, 4, + 1, 1, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | + FB_SYNC_EXT, FB_VMODE_NONINTERLACED, 0,}, { @@ -338,6 +339,7 @@ static int handle_edid(int *pixclk) return 0; } +extern int g_di1_tvout; static int __init mxc_init_fb(void) { int pixclk = 0; @@ -350,12 +352,15 @@ static int __init mxc_init_fb(void) fb_data[0].mode_str = NULL; fb_data[1].mode_str = NULL; } + g_di1_tvout = 1; + /* DI1: Dumb LCD */ if (enable_wvga) { fb_data[1].interface_pix_fmt = IPU_PIX_FMT_RGB565; fb_data[1].mode_str = "800x480M-16@55"; } + /* DI0: lVDS */ if (enable_mitsubishi_xga) { fb_data[0].interface_pix_fmt = IPU_PIX_FMT_LVDS666; fb_data[0].mode = &(video_modes[1]); @@ -385,49 +390,73 @@ static int __init mxc_init_fb(void) if (cpu_is_mx51_rev(CHIP_REV_1_1) == 2) handle_edid(&pixclk); - if (enable_vga) + if (enable_vga) { printk(KERN_INFO "VGA monitor is primary\n"); - else if (enable_wvga) + g_di1_tvout = 0; + } else if (enable_wvga) { printk(KERN_INFO "WVGA LCD panel is primary\n"); - else if (!enable_tv) + g_di1_tvout = 0; + } else if (enable_tv == 2) + printk(KERN_INFO "HDTV is primary\n"); + else printk(KERN_INFO "DVI monitor is primary\n"); if (enable_tv) { - printk(KERN_INFO "TV is specified as %d\n", enable_tv); - if (!fb_data[0].mode) { - fb_data[0].mode = &(video_modes[0]); - if (!enable_wvga) - fb_data[1].mode_str = "800x600M-16@60"; - } - } - - if (enable_tv) { - struct clk *clk, *di_clk; - clk = clk_get(NULL, "pll3"); - di_clk = clk_get(NULL, "ipu_di0_clk"); - clk_disable(clk); - clk_disable(di_clk); - clk_set_rate(clk, 297000000); - clk_set_rate(di_clk, 297000000 / 4); - clk_enable(clk); - clk_enable(di_clk); - clk_put(di_clk); - clk_put(clk); + printk(KERN_INFO "HDTV is specified as %d\n", enable_tv); + fb_data[1].interface_pix_fmt = IPU_PIX_FMT_YUV444; + fb_data[1].mode = &(video_modes[0]); } /* Once a customer knows the platform configuration, this should be simplified to what is desired. */ if (enable_vga || enable_wvga || enable_tv == 2) { - (void)platform_device_register(&mxc_fb_device[1]); /* VGA */ + /* + * DI1 -> DP-BG channel: + * + * dev di-out-fmt default-videmode + * + * 1. VGA RGB 1024x768M-16@60 + * 2. WVGA RGB 800x480M-16@55 + * 3. TVE YUV video_modes[0] + */ + (void)platform_device_register(&mxc_fb_device[1]); if (fb_data[0].mode_str || fb_data[0].mode) + /* + * DI0 -> DC channel: + * + * dev di-out-fmt default-videmode + * + * 1. LVDS RGB video_modes[1] + * 2. DVI RGB 1024x768M-16@60 + */ (void)platform_device_register(&mxc_fb_device[0]); } else { - (void)platform_device_register(&mxc_fb_device[0]); /* DVI */ + /* + * DI0 -> DP-BG channel: + * + * dev di-out-fmt default-videmode + * + * 1. LVDS RGB video_modes[1] + * 2. DVI RGB 1024x768M-16@60 + */ + (void)platform_device_register(&mxc_fb_device[0]); if (fb_data[1].mode_str || fb_data[1].mode) + /* + * DI1 -> DC channel: + * + * dev di-out-fmt default-videmode + * + * 1. VGA RGB 1024x768M-16@60 + * 2. WVGA RGB 800x480M-16@55 + * 3. TVE YUV video_modes[0] + */ (void)platform_device_register(&mxc_fb_device[1]); } + /* + * DI0/1 DP-FG channel: + */ (void)platform_device_register(&mxc_fb_device[2]); return 0; @@ -466,7 +495,7 @@ static int __init tv_setup(char *s) return 1; } -__setup("tv", tv_setup); +__setup("hdtv", tv_setup); #else static inline void mxc_init_fb(void) { diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c index 035d0c9e4519..d7cc2107046e 100644 --- a/drivers/mxc/ipu3/ipu_disp.c +++ b/drivers/mxc/ipu3/ipu_disp.c @@ -56,6 +56,7 @@ struct dp_csc_param_t { int dmfc_type_setup; static int dmfc_size_28, dmfc_size_29, dmfc_size_24, dmfc_size_27, dmfc_size_23; +int g_di1_tvout; void _ipu_dmfc_init(int dmfc_type, int first) { @@ -965,21 +966,23 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, dev_dbg(g_ipu_dev, "pixel clk = %d\n", pixel_clk); if (sig.ext_clk) { - /* Set the PLL to be an even multiple of the pixel clock. */ - if ((clk_get_usecount(g_pixel_clk[0]) == 0) && - (clk_get_usecount(g_pixel_clk[1]) == 0)) { - di_parent = clk_get_parent(g_di_clk[disp]); - rounded_pixel_clk = - clk_round_rate(g_pixel_clk[disp], pixel_clk); - div = clk_get_rate(di_parent) / rounded_pixel_clk; - if (div % 2) - div++; - - if (clk_get_rate(di_parent) != div * rounded_pixel_clk) - clk_set_rate(di_parent, div * rounded_pixel_clk); - msleep(10); - clk_set_rate(g_di_clk[disp], 2 * rounded_pixel_clk); - msleep(10); + if (!(g_di1_tvout && (disp == 1))) { /* not round div for tvout*/ + /* Set the PLL to be an even multiple of the pixel clock. */ + if ((clk_get_usecount(g_pixel_clk[0]) == 0) && + (clk_get_usecount(g_pixel_clk[1]) == 0)) { + di_parent = clk_get_parent(g_di_clk[disp]); + rounded_pixel_clk = + clk_round_rate(g_pixel_clk[disp], pixel_clk); + div = clk_get_rate(di_parent) / rounded_pixel_clk; + if (div % 2) + div++; + + if (clk_get_rate(di_parent) != div * rounded_pixel_clk) + clk_set_rate(di_parent, div * rounded_pixel_clk); + msleep(10); + clk_set_rate(g_di_clk[disp], 2 * rounded_pixel_clk); + msleep(10); + } } clk_set_parent(g_pixel_clk[disp], g_di_clk[disp]); } else { diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index f9b8f6b0f84c..39c9fdd207af 100644 --- a/drivers/video/mxc/mxc_ipuv3_fb.c +++ b/drivers/video/mxc/mxc_ipuv3_fb.c @@ -168,6 +168,8 @@ static int _setup_disp_channel1(struct fb_info *fbi) if (mxc_fbi_tmp->ipu_ch == MEM_BG_SYNC) { fbi->var.vmode = registered_fb[i]->var.vmode; + mxc_fbi->ipu_di_pix_fmt = + mxc_fbi_tmp->ipu_di_pix_fmt; break; } } diff --git a/drivers/video/mxc/tve.c b/drivers/video/mxc/tve.c index 061d65a7cd20..74c98521bfc1 100644 --- a/drivers/video/mxc/tve.c +++ b/drivers/video/mxc/tve.c @@ -221,8 +221,8 @@ static int tve_setup(int mode) { u32 reg; struct clk *pll3_clk; - unsigned long pll3_clock_rate = 216000000; - struct clk *ipu_di0_clk; + unsigned long pll3_clock_rate = 216000000, di1_clock_rate = 27000000; + struct clk *ipu_di1_clk; if (tve.cur_mode == mode) return 0; @@ -233,25 +233,23 @@ static int tve_setup(int mode) case TVOUT_FMT_PAL: case TVOUT_FMT_NTSC: pll3_clock_rate = 216000000; + di1_clock_rate = 27000000; break; case TVOUT_FMT_720P60: pll3_clock_rate = 297000000; + di1_clock_rate = 74250000; break; } if (enabled) clk_disable(tve.clk); pll3_clk = clk_get(NULL, "pll3"); - ipu_di0_clk = clk_get(NULL, "ipu_di0_clk"); - if ((clk_get_parent(ipu_di0_clk) == pll3_clk) && - (clk_get_rate(pll3_clk) != pll3_clock_rate)) { - printk(KERN_INFO "Cannot setup TV since display is using PLL3\n"); - return -EINVAL; - } + ipu_di1_clk = clk_get(NULL, "ipu_di1_clk"); clk_disable(pll3_clk); clk_set_rate(pll3_clk, pll3_clock_rate); clk_enable(pll3_clk); + clk_set_rate(ipu_di1_clk, di1_clock_rate); clk_enable(tve.clk); @@ -616,6 +614,7 @@ static int _tve_get_revision(void) return rev; } +extern int g_di1_tvout; static int tve_probe(struct platform_device *pdev) { int ret, i; @@ -623,6 +622,11 @@ static int tve_probe(struct platform_device *pdev) struct tve_platform_data *plat_data = pdev->dev.platform_data; u32 conf_reg; + if (!g_di1_tvout) { + pr_debug("TVE: DI1 was occupied by other device,TVE will not enable\n"); + return -EBUSY; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) return -ENOMEM; |