OMAP: DSS2: Implement OMAP4 DSS fclk support

Add dss.dpll4_m4_ck (DSS FCLK) initialization for OMAP4. This is used
to compute the pixel clock for DPI interface and also to reconfigure
the DSS FCLK to the desired rate, corresponding to the rate computed
for pixel clock.

Adding these cpu_is_44xx() checks are meant to be temporary, until a
cleaner implementation to manage these checks are added. Currently this
is needed to get DVI display running on OMAP4 PandaBoard

Signed-off-by: Raghuveer Murthy <raghuveer.murthy@ti.com>
[tomi.valkeinen@ti.com: minor changes due to conflicts]
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 9d23902..3f1fee6 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -256,7 +256,7 @@
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630())
+		if (cpu_is_omap3630() || cpu_is_omap44xx())
 			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
 					fclk_name, fclk_real_name,
 					dpll4_ck_rate,
@@ -394,9 +394,12 @@
 {
 	if (dss.dpll4_m4_ck) {
 		unsigned long prate;
+		u16 fck_div_max = 16;
 
-		if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) ||
-				cinfo->fck_div == 0)
+		if (cpu_is_omap3630() || cpu_is_omap44xx())
+			fck_div_max = 32;
+
+		if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
 			return -EINVAL;
 
 		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
@@ -442,7 +445,7 @@
 
 		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
 
-		if (cpu_is_omap3630())
+		if (cpu_is_omap3630() || cpu_is_omap44xx())
 			cinfo->fck_div = prate / (cinfo->fck);
 		else
 			cinfo->fck_div = prate / (cinfo->fck / 2);
@@ -471,7 +474,7 @@
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div;
+	u16 fck_div, fck_div_max = 16;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -504,7 +507,7 @@
 	memset(&best_dss, 0, sizeof(best_dss));
 	memset(&best_dispc, 0, sizeof(best_dispc));
 
-	if (cpu_is_omap24xx()) {
+	if (dss.dpll4_m4_ck == NULL) {
 		struct dispc_clock_info cur_dispc;
 		/* XXX can we change the clock on omap2? */
 		fck = dss_clk_get_rate(DSS_CLK_FCK);
@@ -519,12 +522,14 @@
 		best_dispc = cur_dispc;
 
 		goto found;
-	} else if (cpu_is_omap34xx()) {
-		for (fck_div = (cpu_is_omap3630() ? 32 : 16);
-					fck_div > 0; --fck_div) {
+	} else {
+		if (cpu_is_omap3630() || cpu_is_omap44xx())
+			fck_div_max = 32;
+
+		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (cpu_is_omap3630())
+			if (fck_div_max == 32)
 				fck = prate / fck_div;
 			else
 				fck = prate / fck_div * 2;
@@ -552,8 +557,6 @@
 					goto found;
 			}
 		}
-	} else {
-		BUG();
 	}
 
 found:
@@ -684,6 +687,13 @@
 			r = PTR_ERR(dpll4_m4_ck);
 			goto fail1;
 		}
+	} else if (cpu_is_omap44xx()) {
+		dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
+		if (IS_ERR(dpll4_m4_ck)) {
+			DSSERR("Failed to get dpll4_m4_ck\n");
+			r = PTR_ERR(dpll4_m4_ck);
+			goto fail1;
+		}
 	} else { /* omap24xx */
 		dpll4_m4_ck = NULL;
 	}