aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2011-09-13 08:58:41 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-09-30 09:17:25 -0400
commitc3dc6a7afb47735b82a4c0061e814454a649dbfc (patch)
treed04f7a341aed9d9aae42d33479526f9d26c7e74b /drivers/video
parentdac57a05fcf4808bbc91a96a034cae84716f0077 (diff)
OMAPDSS: DISPC: Get correct pixel clock for TV manager
dispc_mgr_pclk_rate() is used to calculate minimum required functional clock for scaling in calc_fclk() and calc_fclk_five_taps(). This function returns the correct pixel clock for LCD and LCD2 managers, but not for TV manager. Extend this function so that it gets the correct pixel clock for TV manager. This also prevents the crash we get when we try to scale overlays connected to TV manager. The current code leads to a BUG() being executed if we call dispc_mgr_pclk_rate() for the TV manager. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/dispc.c37
-rw-r--r--drivers/video/omap2/dss/dss.h12
-rw-r--r--drivers/video/omap2/dss/hdmi.c6
-rw-r--r--drivers/video/omap2/dss/venc.c8
4 files changed, 52 insertions, 11 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a96fc41d7668..57074b33f024 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -427,6 +427,14 @@ static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
427 return false; 427 return false;
428} 428}
429 429
430static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
431{
432 struct omap_overlay_manager *mgr =
433 omap_dss_get_overlay_manager(channel);
434
435 return mgr ? mgr->device : NULL;
436}
437
430bool dispc_mgr_go_busy(enum omap_channel channel) 438bool dispc_mgr_go_busy(enum omap_channel channel)
431{ 439{
432 int bit; 440 int bit;
@@ -1619,7 +1627,6 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1619 enum omap_color_mode color_mode) 1627 enum omap_color_mode color_mode)
1620{ 1628{
1621 u32 fclk = 0; 1629 u32 fclk = 0;
1622 /* FIXME venc pclk? */
1623 u64 tmp, pclk = dispc_mgr_pclk_rate(channel); 1630 u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
1624 1631
1625 if (height > out_height) { 1632 if (height > out_height) {
@@ -1676,7 +1683,6 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1676 else 1683 else
1677 vf = 1; 1684 vf = 1;
1678 1685
1679 /* FIXME venc pclk? */
1680 return dispc_mgr_pclk_rate(channel) * vf * hf; 1686 return dispc_mgr_pclk_rate(channel) * vf * hf;
1681} 1687}
1682 1688
@@ -2415,17 +2421,32 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
2415 2421
2416unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) 2422unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
2417{ 2423{
2418 int pcd;
2419 unsigned long r; 2424 unsigned long r;
2420 u32 l;
2421 2425
2422 l = dispc_read_reg(DISPC_DIVISORo(channel)); 2426 if (dispc_mgr_is_lcd(channel)) {
2427 int pcd;
2428 u32 l;
2423 2429
2424 pcd = FLD_GET(l, 7, 0); 2430 l = dispc_read_reg(DISPC_DIVISORo(channel));
2425 2431
2426 r = dispc_mgr_lclk_rate(channel); 2432 pcd = FLD_GET(l, 7, 0);
2427 2433
2428 return r / pcd; 2434 r = dispc_mgr_lclk_rate(channel);
2435
2436 return r / pcd;
2437 } else {
2438 struct omap_dss_device *dssdev =
2439 dispc_mgr_get_device(channel);
2440
2441 switch (dssdev->type) {
2442 case OMAP_DISPLAY_TYPE_VENC:
2443 return venc_get_pixel_clock();
2444 case OMAP_DISPLAY_TYPE_HDMI:
2445 return hdmi_get_pixel_clock();
2446 default:
2447 BUG();
2448 }
2449 }
2429} 2450}
2430 2451
2431void dispc_dump_clocks(struct seq_file *s) 2452void dispc_dump_clocks(struct seq_file *s)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index dff9b799d51e..47eebd804153 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -450,6 +450,7 @@ int venc_init_platform_driver(void);
450void venc_uninit_platform_driver(void); 450void venc_uninit_platform_driver(void);
451void venc_dump_regs(struct seq_file *s); 451void venc_dump_regs(struct seq_file *s);
452int venc_init_display(struct omap_dss_device *display); 452int venc_init_display(struct omap_dss_device *display);
453unsigned long venc_get_pixel_clock(void);
453#else 454#else
454static inline int venc_init_platform_driver(void) 455static inline int venc_init_platform_driver(void)
455{ 456{
@@ -458,6 +459,11 @@ static inline int venc_init_platform_driver(void)
458static inline void venc_uninit_platform_driver(void) 459static inline void venc_uninit_platform_driver(void)
459{ 460{
460} 461}
462static inline unsigned long venc_get_pixel_clock(void)
463{
464 WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__);
465 return 0;
466}
461#endif 467#endif
462 468
463/* HDMI */ 469/* HDMI */
@@ -465,6 +471,7 @@ static inline void venc_uninit_platform_driver(void)
465int hdmi_init_platform_driver(void); 471int hdmi_init_platform_driver(void);
466void hdmi_uninit_platform_driver(void); 472void hdmi_uninit_platform_driver(void);
467int hdmi_init_display(struct omap_dss_device *dssdev); 473int hdmi_init_display(struct omap_dss_device *dssdev);
474unsigned long hdmi_get_pixel_clock(void);
468#else 475#else
469static inline int hdmi_init_display(struct omap_dss_device *dssdev) 476static inline int hdmi_init_display(struct omap_dss_device *dssdev)
470{ 477{
@@ -477,6 +484,11 @@ static inline int hdmi_init_platform_driver(void)
477static inline void hdmi_uninit_platform_driver(void) 484static inline void hdmi_uninit_platform_driver(void)
478{ 485{
479} 486}
487static inline unsigned long hdmi_get_pixel_clock(void)
488{
489 WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
490 return 0;
491}
480#endif 492#endif
481int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); 493int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
482void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); 494void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 781867002662..2f554ae6858e 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -266,6 +266,12 @@ static void update_hdmi_timings(struct hdmi_config *cfg,
266 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol; 266 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
267} 267}
268 268
269unsigned long hdmi_get_pixel_clock(void)
270{
271 /* HDMI Pixel Clock in Mhz */
272 return hdmi.ip_data.cfg.timings.timings.pixel_clock * 10000;
273}
274
269static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, 275static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
270 struct hdmi_pll_info *pi) 276 struct hdmi_pll_info *pi)
271{ 277{
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 53319580417c..7533458ba4d2 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -463,9 +463,11 @@ static void venc_power_off(struct omap_dss_device *dssdev)
463 regulator_disable(venc.vdda_dac_reg); 463 regulator_disable(venc.vdda_dac_reg);
464} 464}
465 465
466 466unsigned long venc_get_pixel_clock(void)
467 467{
468 468 /* VENC Pixel Clock in Mhz */
469 return 13500000;
470}
469 471
470/* driver */ 472/* driver */
471static int venc_panel_probe(struct omap_dss_device *dssdev) 473static int venc_panel_probe(struct omap_dss_device *dssdev)