diff options
author | Chandrabhanu Mahapatra <cmahapatra@ti.com> | 2012-07-11 09:06:18 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-08-22 04:43:03 -0400 |
commit | 185bae1095188aa199c9be64d6030d8dbfc65e0a (patch) | |
tree | 7f2adbe00171a99ee425f73af17ec3a1d2e57b81 /drivers/video/omap2/dss/dss.c | |
parent | ba1bc5bb1da5151f94031909ff775b0b4a1871c1 (diff) |
OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
All the cpu_is checks have been moved to dss_init_features function providing a
much more generic and cleaner interface. The OMAP version and revision specific
initializations in various functions are cleaned and the necessary data are
moved to dss_features structure which is local to dss.c.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2/dss/dss.c')
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 120 |
1 files changed, 79 insertions, 41 deletions
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index e2e0fa453c6..31a553a6ee6 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/gfp.h> | ||
34 | 35 | ||
35 | #include <video/omapdss.h> | 36 | #include <video/omapdss.h> |
36 | 37 | ||
@@ -65,6 +66,12 @@ struct dss_reg { | |||
65 | static int dss_runtime_get(void); | 66 | static int dss_runtime_get(void); |
66 | static void dss_runtime_put(void); | 67 | static void dss_runtime_put(void); |
67 | 68 | ||
69 | struct dss_features { | ||
70 | u8 fck_div_max; | ||
71 | u8 dss_fck_multiplier; | ||
72 | const char *clk_name; | ||
73 | }; | ||
74 | |||
68 | static struct { | 75 | static struct { |
69 | struct platform_device *pdev; | 76 | struct platform_device *pdev; |
70 | void __iomem *base; | 77 | void __iomem *base; |
@@ -83,6 +90,8 @@ static struct { | |||
83 | 90 | ||
84 | bool ctx_valid; | 91 | bool ctx_valid; |
85 | u32 ctx[DSS_SZ_REGS / sizeof(u32)]; | 92 | u32 ctx[DSS_SZ_REGS / sizeof(u32)]; |
93 | |||
94 | const struct dss_features *feat; | ||
86 | } dss; | 95 | } dss; |
87 | 96 | ||
88 | static const char * const dss_generic_clk_source_names[] = { | 97 | static const char * const dss_generic_clk_source_names[] = { |
@@ -91,6 +100,30 @@ static const char * const dss_generic_clk_source_names[] = { | |||
91 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", | 100 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", |
92 | }; | 101 | }; |
93 | 102 | ||
103 | static const struct dss_features omap24xx_dss_feats __initconst = { | ||
104 | .fck_div_max = 16, | ||
105 | .dss_fck_multiplier = 2, | ||
106 | .clk_name = NULL, | ||
107 | }; | ||
108 | |||
109 | static const struct dss_features omap34xx_dss_feats __initconst = { | ||
110 | .fck_div_max = 16, | ||
111 | .dss_fck_multiplier = 2, | ||
112 | .clk_name = "dpll4_m4_ck", | ||
113 | }; | ||
114 | |||
115 | static const struct dss_features omap3630_dss_feats __initconst = { | ||
116 | .fck_div_max = 32, | ||
117 | .dss_fck_multiplier = 1, | ||
118 | .clk_name = "dpll4_m4_ck", | ||
119 | }; | ||
120 | |||
121 | static const struct dss_features omap44xx_dss_feats __initconst = { | ||
122 | .fck_div_max = 32, | ||
123 | .dss_fck_multiplier = 1, | ||
124 | .clk_name = "dpll_per_m5x2_ck", | ||
125 | }; | ||
126 | |||
94 | static inline void dss_write_reg(const struct dss_reg idx, u32 val) | 127 | static inline void dss_write_reg(const struct dss_reg idx, u32 val) |
95 | { | 128 | { |
96 | __raw_writel(val, dss.base + idx.idx); | 129 | __raw_writel(val, dss.base + idx.idx); |
@@ -236,7 +269,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src) | |||
236 | return dss_generic_clk_source_names[clk_src]; | 269 | return dss_generic_clk_source_names[clk_src]; |
237 | } | 270 | } |
238 | 271 | ||
239 | |||
240 | void dss_dump_clocks(struct seq_file *s) | 272 | void dss_dump_clocks(struct seq_file *s) |
241 | { | 273 | { |
242 | unsigned long dpll4_ck_rate; | 274 | unsigned long dpll4_ck_rate; |
@@ -259,18 +291,10 @@ void dss_dump_clocks(struct seq_file *s) | |||
259 | 291 | ||
260 | seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); | 292 | seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); |
261 | 293 | ||
262 | if (cpu_is_omap3630() || cpu_is_omap44xx()) | 294 | seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n", |
263 | seq_printf(s, "%s (%s) = %lu / %lu = %lu\n", | 295 | fclk_name, fclk_real_name, dpll4_ck_rate, |
264 | fclk_name, fclk_real_name, | 296 | dpll4_ck_rate / dpll4_m4_ck_rate, |
265 | dpll4_ck_rate, | 297 | dss.feat->dss_fck_multiplier, fclk_rate); |
266 | dpll4_ck_rate / dpll4_m4_ck_rate, | ||
267 | fclk_rate); | ||
268 | else | ||
269 | seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n", | ||
270 | fclk_name, fclk_real_name, | ||
271 | dpll4_ck_rate, | ||
272 | dpll4_ck_rate / dpll4_m4_ck_rate, | ||
273 | fclk_rate); | ||
274 | } else { | 298 | } else { |
275 | seq_printf(s, "%s (%s) = %lu\n", | 299 | seq_printf(s, "%s (%s) = %lu\n", |
276 | fclk_name, fclk_real_name, | 300 | fclk_name, fclk_real_name, |
@@ -470,7 +494,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, | |||
470 | 494 | ||
471 | unsigned long fck, max_dss_fck; | 495 | unsigned long fck, max_dss_fck; |
472 | 496 | ||
473 | u16 fck_div, fck_div_max = 16; | 497 | u16 fck_div; |
474 | 498 | ||
475 | int match = 0; | 499 | int match = 0; |
476 | int min_fck_per_pck; | 500 | int min_fck_per_pck; |
@@ -480,9 +504,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, | |||
480 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | 504 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); |
481 | 505 | ||
482 | fck = clk_get_rate(dss.dss_clk); | 506 | fck = clk_get_rate(dss.dss_clk); |
483 | if (req_pck == dss.cache_req_pck && | 507 | if (req_pck == dss.cache_req_pck && prate == dss.cache_prate && |
484 | ((cpu_is_omap34xx() && prate == dss.cache_prate) || | 508 | dss.cache_dss_cinfo.fck == fck) { |
485 | dss.cache_dss_cinfo.fck == fck)) { | ||
486 | DSSDBG("dispc clock info found from cache.\n"); | 509 | DSSDBG("dispc clock info found from cache.\n"); |
487 | *dss_cinfo = dss.cache_dss_cinfo; | 510 | *dss_cinfo = dss.cache_dss_cinfo; |
488 | *dispc_cinfo = dss.cache_dispc_cinfo; | 511 | *dispc_cinfo = dss.cache_dispc_cinfo; |
@@ -519,16 +542,10 @@ retry: | |||
519 | 542 | ||
520 | goto found; | 543 | goto found; |
521 | } else { | 544 | } else { |
522 | if (cpu_is_omap3630() || cpu_is_omap44xx()) | 545 | for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) { |
523 | fck_div_max = 32; | ||
524 | |||
525 | for (fck_div = fck_div_max; fck_div > 0; --fck_div) { | ||
526 | struct dispc_clock_info cur_dispc; | 546 | struct dispc_clock_info cur_dispc; |
527 | 547 | ||
528 | if (fck_div_max == 32) | 548 | fck = prate / fck_div * dss.feat->dss_fck_multiplier; |
529 | fck = prate / fck_div; | ||
530 | else | ||
531 | fck = prate / fck_div * 2; | ||
532 | 549 | ||
533 | if (fck > max_dss_fck) | 550 | if (fck > max_dss_fck) |
534 | continue; | 551 | continue; |
@@ -645,22 +662,11 @@ static int dss_get_clocks(void) | |||
645 | 662 | ||
646 | dss.dss_clk = clk; | 663 | dss.dss_clk = clk; |
647 | 664 | ||
648 | if (cpu_is_omap34xx()) { | 665 | clk = clk_get(NULL, dss.feat->clk_name); |
649 | clk = clk_get(NULL, "dpll4_m4_ck"); | 666 | if (IS_ERR(clk)) { |
650 | if (IS_ERR(clk)) { | 667 | DSSERR("Failed to get %s\n", dss.feat->clk_name); |
651 | DSSERR("Failed to get dpll4_m4_ck\n"); | 668 | r = PTR_ERR(clk); |
652 | r = PTR_ERR(clk); | 669 | goto err; |
653 | goto err; | ||
654 | } | ||
655 | } else if (cpu_is_omap44xx()) { | ||
656 | clk = clk_get(NULL, "dpll_per_m5x2_ck"); | ||
657 | if (IS_ERR(clk)) { | ||
658 | DSSERR("Failed to get dpll_per_m5x2_ck\n"); | ||
659 | r = PTR_ERR(clk); | ||
660 | goto err; | ||
661 | } | ||
662 | } else { /* omap24xx */ | ||
663 | clk = NULL; | ||
664 | } | 670 | } |
665 | 671 | ||
666 | dss.dpll4_m4_ck = clk; | 672 | dss.dpll4_m4_ck = clk; |
@@ -716,6 +722,34 @@ void dss_debug_dump_clocks(struct seq_file *s) | |||
716 | } | 722 | } |
717 | #endif | 723 | #endif |
718 | 724 | ||
725 | static int __init dss_init_features(struct device *dev) | ||
726 | { | ||
727 | const struct dss_features *src; | ||
728 | struct dss_features *dst; | ||
729 | |||
730 | dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL); | ||
731 | if (!dst) { | ||
732 | dev_err(dev, "Failed to allocate local DSS Features\n"); | ||
733 | return -ENOMEM; | ||
734 | } | ||
735 | |||
736 | if (cpu_is_omap24xx()) | ||
737 | src = &omap24xx_dss_feats; | ||
738 | else if (cpu_is_omap34xx()) | ||
739 | src = &omap34xx_dss_feats; | ||
740 | else if (cpu_is_omap3630()) | ||
741 | src = &omap3630_dss_feats; | ||
742 | else if (cpu_is_omap44xx()) | ||
743 | src = &omap44xx_dss_feats; | ||
744 | else | ||
745 | return -ENODEV; | ||
746 | |||
747 | memcpy(dst, src, sizeof(*dst)); | ||
748 | dss.feat = dst; | ||
749 | |||
750 | return 0; | ||
751 | } | ||
752 | |||
719 | /* DSS HW IP initialisation */ | 753 | /* DSS HW IP initialisation */ |
720 | static int __init omap_dsshw_probe(struct platform_device *pdev) | 754 | static int __init omap_dsshw_probe(struct platform_device *pdev) |
721 | { | 755 | { |
@@ -725,6 +759,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) | |||
725 | 759 | ||
726 | dss.pdev = pdev; | 760 | dss.pdev = pdev; |
727 | 761 | ||
762 | r = dss_init_features(&dss.pdev->dev); | ||
763 | if (r) | ||
764 | return r; | ||
765 | |||
728 | dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); | 766 | dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); |
729 | if (!dss_mem) { | 767 | if (!dss_mem) { |
730 | DSSERR("can't get IORESOURCE_MEM DSS\n"); | 768 | DSSERR("can't get IORESOURCE_MEM DSS\n"); |