All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] OMAPDSS: Remove cpu_is checks
@ 2012-08-07  8:39 ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:27 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Hi everyone,
the patch series aims at cleaning up of DSS of cpu_is checks thereby making it
more generic.

The 1st patch cleans up cpu_is checks from DISPC code.
The 2nd patch removes unused functions from DSS code.
The 3rd patch cleans up cpu_is checks from DSS code.
The 4th patch removes cpu_is checks from VENC code.
The 5th patch disables VENC support on OMAP4.
The 6th patch removes cpu_is checks from DPI code and replaces it with a
dss feature.

All your comments and suggestions are welcome.

Regards,
Chandrabhanu

Chandrabhanu Mahapatra (6):
  OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  OMAPDSS: DSS: Remove redundant functions
  OMAPDSS: DSS: Remove cpu_is_xxxx checks
  OMAPDSS: VENC: Remove cpu_is_xxxx checks
  ARM: OMAP: Disable venc for OMAP4
  OMAPDSS: DPI: Remove cpu_is_xxxx checks

 arch/arm/mach-omap2/display.c          |    1 -
 drivers/video/omap2/dss/dispc.c        |  386 +++++++++++++++++++-------------
 drivers/video/omap2/dss/dpi.c          |   12 +-
 drivers/video/omap2/dss/dss.c          |  155 +++++++------
 drivers/video/omap2/dss/dss.h          |   73 +++++-
 drivers/video/omap2/dss/dss_features.c |   83 +++++++
 drivers/video/omap2/dss/dss_features.h |    4 +
 drivers/video/omap2/dss/venc.c         |   11 -
 8 files changed, 465 insertions(+), 260 deletions(-)

-- 
1.7.10


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  8:39 ` Chandrabhanu Mahapatra
@ 2012-08-07  8:39   ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:27 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The cpu_is checks have been removed from DISPC providing it a much generic and
cleaner interface. The OMAP version and revision specific functions are
initialized by dispc_ops structure in dss features.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c        |  386 +++++++++++++++++++-------------
 drivers/video/omap2/dss/dss.h          |   48 ++++
 drivers/video/omap2/dss/dss_features.c |   42 ++++
 drivers/video/omap2/dss/dss_features.h |    2 +
 4 files changed, 317 insertions(+), 161 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..ad63302 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -101,6 +101,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_ops *ops;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1941,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1971,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.ops->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.ops->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
 	}
+	return 0;
+}
+
+int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth =
+				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.ops->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2139,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth =
-				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width == out_width && height == out_height)
 		return 0;
@@ -2017,118 +2165,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.ops->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2601,27 +2648,28 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 		height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT);
 }
 
-static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
+bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > 64 ||
+			hfp < 1 || hfp > 256 ||
+			hbp < 1 || hbp > 256 ||
+			vsw < 1 || vsw > 64  ||
+			vfp < 0 || vfp > 255 ||
+			vbp < 0 || vbp > 255)
+		return false;
+	return true;
+}
+bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp)
+{
+	if (hsw < 1 || hsw > 256 ||
+			hfp < 1  || hfp > 4096 ||
+			hbp < 1  || hbp > 4096 ||
+			vsw < 1  || vsw > 256  ||
+			vfp < 0  || vfp > 4095 ||
+			vbp < 0  || vbp > 4095)
+		return false;
 	return true;
 }
 
@@ -2633,7 +2681,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
 
 	if (dss_mgr_is_lcd(channel))
-		timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
+		timings_ok =  timings_ok &&
+			dispc.ops->lcd_timings_ok(timings->hsw,
 						timings->hfp, timings->hbp,
 						timings->vsw, timings->vfp,
 						timings->vbp);
@@ -2641,6 +2690,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	return timings_ok;
 }
 
+void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
+			FLD_VAL(hbp-1, 27, 20);
+	timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
+			FLD_VAL(vbp, 27, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
+void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
+			FLD_VAL(hbp-1, 31, 20);
+	timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
+			FLD_VAL(vbp, 31, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
 static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		int hfp, int hbp, int vsw, int vfp, int vbp,
 		enum omap_dss_signal_level vsync_level,
@@ -2650,25 +2727,10 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		enum omap_dss_signal_edge sync_pclk_edge)
 
 {
-	u32 timing_h, timing_v, l;
+	u32 l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
-
-	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
-	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+	dispc.ops->set_lcd_timings_hv(channel, hsw, hfp, hbp, vsw, vfp, vbp);
 
 	switch (data_pclk_edge) {
 	case OMAPDSS_DRIVE_SIG_RISING_EDGE:
@@ -3725,6 +3787,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	dispc_init_ops(dispc.ops);
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f67afe7..d87b885 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -171,6 +171,21 @@ struct dss_lcd_mgr_config {
 	int lcden_sig_polarity;
 };
 
+struct dispc_ops {
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+	bool (*lcd_timings_ok) (int hsw, int hfp, int hbp,
+			int vsw, int vfp, int vbp);
+	void (*set_lcd_timings_hv) (enum omap_channel channel, int hsw, int hfp,
+			int hbp, int vsw, int vfp, int vbp);
+};
+
 struct seq_file;
 struct platform_device;
 
@@ -457,6 +472,39 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
 void dispc_mgr_setup(enum omap_channel channel,
 		struct omap_overlay_manager_info *info);
 
+int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+
+unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+
+bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+
+void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp);
+void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp);
+
 /* VENC */
 #ifdef CONFIG_OMAP2_DSS_VENC
 int venc_init_platform_driver(void) __init;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..b8d5095 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -567,6 +567,48 @@ static const struct omap_dss_features omap4_dss_features = {
 	.burst_size_unit = 16,
 };
 
+static const struct dispc_ops omap2_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_ops omap3_2_1_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_ops omap3_3_0_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
+static const struct dispc_ops omap4_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
+void dispc_init_ops(const struct dispc_ops *ops)
+{
+	if (cpu_is_omap24xx()) {
+		ops = &omap2_dispc_ops;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			ops = &omap3_2_1_dispc_ops;
+		else
+			ops = &omap3_3_0_dispc_ops;
+	} else {
+		ops = &omap4_dispc_ops;
+	}
+}
+
 #if defined(CONFIG_OMAP4_DSS_HDMI)
 /* HDMI OMAP4 Functions*/
 static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..d03777a 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -120,4 +120,6 @@ void dss_features_init(void);
 #if defined(CONFIG_OMAP4_DSS_HDMI)
 void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
 #endif
+
+void dispc_init_ops(const struct dispc_ops *ops);
 #endif
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 2/6] OMAPDSS: DSS: Remove redundant functions
  2012-08-07  8:39 ` Chandrabhanu Mahapatra
@ 2012-08-07  8:39   ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:27 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Functions dss_calc_clock_rates() and dss_get_clock_div() are removed as these
functions have become redundant and no longer used.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |   45 -----------------------------------------
 drivers/video/omap2/dss/dss.h |    2 --
 2 files changed, 47 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 04b4586..7b1c6ac 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 	}
 }
 
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-		u16 fck_div_max = 16;
-
-		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));
-
-		cinfo->fck = prate / cinfo->fck_div;
-	} else {
-		if (cinfo->fck_div != 0)
-			return -EINVAL;
-		cinfo->fck = clk_get_rate(dss.dss_clk);
-	}
-
-	return 0;
-}
-
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
 	if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
 	return 0;
 }
 
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
-	cinfo->fck = clk_get_rate(dss.dss_clk);
-
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			cinfo->fck_div = prate / (cinfo->fck);
-		else
-			cinfo->fck_div = prate / (cinfo->fck / 2);
-	} else {
-		cinfo->fck_div = 0;
-	}
-
-	return 0;
-}
-
 unsigned long dss_get_dpll4_rate(void)
 {
 	if (dss.dpll4_m4_ck)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d87b885..5773c86 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -311,9 +311,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 3/6] OMAPDSS: DSS: Remove cpu_is_xxxx checks
  2012-08-07  8:39 ` Chandrabhanu Mahapatra
@ 2012-08-07  8:40   ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:28 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The cpu_is checks have been removed from dss.c providing it a much generic and
cleaner interface. The OMAP version and revision specific functions are
initialized by dss_ops structure in dss features.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c          |  114 ++++++++++++++++++++++----------
 drivers/video/omap2/dss/dss.h          |   23 ++++++-
 drivers/video/omap2/dss/dss_features.c |   40 +++++++++++
 drivers/video/omap2/dss/dss_features.h |    1 +
 4 files changed, 141 insertions(+), 37 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..c263da7 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -83,6 +83,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_ops *ops;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -236,6 +238,15 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
 	return dss_generic_clk_source_names[clk_src];
 }
 
+char *set_dump_clk_str_24_34(void)
+{
+	return "%s (%s) = %lu / %lu * 2  = %lu\n";
+}
+
+char *set_dump_clk_str(void)
+{
+	return "%s (%s) = %lu / %lu  = %lu\n";
+}
 
 void dss_dump_clocks(struct seq_file *s)
 {
@@ -254,23 +265,15 @@ void dss_dump_clocks(struct seq_file *s)
 	fclk_rate = clk_get_rate(dss.dss_clk);
 
 	if (dss.dpll4_m4_ck) {
+		char *str = dss.ops->set_str();
+
 		dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
 		dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, str, fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -461,6 +464,35 @@ unsigned long dss_get_dpll4_rate(void)
 		return 0;
 }
 
+u16 get_dss_fck_div_max_24_34(void)
+{
+	return 16;
+}
+
+u16 get_dss_fck_div_max(void)
+{
+	return 32;
+}
+
+bool set_dss_clock_info_34xx(void)
+{
+	unsigned long prate = dss_get_dpll4_rate();
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (prate == dss.cache_prate || dss.cache_dss_cinfo.fck == fck)
+		return true;
+	return false;
+}
+
+bool set_dss_clock_info(void)
+{
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (dss.cache_dss_cinfo.fck == fck)
+		return true;
+	return false;
+}
+
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo)
 {
@@ -470,7 +502,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div, fck_div_max;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -479,10 +511,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
-	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck == dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck == fck)) {
+	if (req_pck == dss.cache_req_pck && dss.ops->set_dss_cinfo()) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,8 +548,7 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
+		fck_div_max = dss.ops->get_fck_div_max();
 
 		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
@@ -619,6 +647,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
 	return REG_GET(DSS_CONTROL, 15, 15);
 }
 
+int dss_get_clk_24xx(struct clk *clk)
+{
+	clk = NULL;
+	return true;
+}
+
+int dss_get_clk_3xxx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll4_m4_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll4_m4_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
+int dss_get_clk_44xx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll_per_m5x2_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll_per_m5x2_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
 static int dss_get_clocks(void)
 {
 	struct clk *clk;
@@ -633,23 +687,9 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
-	}
+	r = dss.ops->get_clk(clk);
+	if (r != true)
+		goto err;
 
 	dss.dpll4_m4_ck = clk;
 
@@ -750,6 +790,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	dss_init_ops(dss.ops);
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5773c86..b756ae1 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -19,7 +19,6 @@
  * You should have received a copy of the GNU General Public License along with
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
 #ifndef __OMAP2_DSS_H
 #define __OMAP2_DSS_H
 
@@ -186,6 +185,15 @@ struct dispc_ops {
 			int hbp, int vsw, int vfp, int vbp);
 };
 
+struct clk;
+
+struct dss_ops {
+	u16 (*get_fck_div_max) (void);
+	bool (*set_dss_cinfo) (void);
+	int (*get_clk) (struct clk *clk);
+	char *(*set_str) (void);
+};
+
 struct seq_file;
 struct platform_device;
 
@@ -315,6 +323,19 @@ int dss_set_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
+u16 get_dss_fck_div_max_24_34(void);
+u16 get_dss_fck_div_max(void);
+
+bool set_dss_clock_info(void);
+bool set_dss_clock_info_34xx(void);
+
+int dss_get_clk_24xx(struct clk *clk);
+int dss_get_clk_3xxx(struct clk *clk);
+int dss_get_clk_44xx(struct clk *clk);
+
+char *set_dump_clk_str_24_34(void);
+char *set_dump_clk_str(void);
+
 /* SDI */
 int sdi_init_platform_driver(void) __init;
 void sdi_uninit_platform_driver(void) __exit;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index b8d5095..6b35200 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -609,6 +609,46 @@ void dispc_init_ops(const struct dispc_ops *ops)
 	}
 }
 
+static const struct dss_ops omap2_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
+	.set_dss_cinfo		=	set_dss_clock_info,
+	.get_clk		=	dss_get_clk_24xx,
+	.set_str		=	set_dump_clk_str_24_34,
+};
+
+static const struct dss_ops omap34_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
+	.set_dss_cinfo		=	set_dss_clock_info_34xx,
+	.get_clk		=	dss_get_clk_3xxx,
+	.set_str		=	set_dump_clk_str_24_34,
+};
+
+static const struct dss_ops omap36_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max,
+	.set_dss_cinfo		=	set_dss_clock_info,
+	.get_clk		=	dss_get_clk_3xxx,
+	.set_str		=	set_dump_clk_str,
+};
+
+static const struct dss_ops omap4_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max,
+	.set_dss_cinfo		=	set_dss_clock_info,
+	.get_clk		=	dss_get_clk_44xx,
+	.set_str		=	set_dump_clk_str,
+};
+
+void dss_init_ops(const struct dss_ops *ops)
+{
+	if (cpu_is_omap24xx())
+		ops = &omap2_dss_ops;
+	else if (cpu_is_omap34xx())
+		ops = &omap34_dss_ops;
+	else if (cpu_is_omap3630())
+		ops = &omap36_dss_ops;
+	else
+		ops = &omap4_dss_ops;
+}
+
 #if defined(CONFIG_OMAP4_DSS_HDMI)
 /* HDMI OMAP4 Functions*/
 static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index d03777a..aa1e4b6 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -122,4 +122,5 @@ void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
 #endif
 
 void dispc_init_ops(const struct dispc_ops *ops);
+void dss_init_ops(const struct dss_ops *ops);
 #endif
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
  2012-08-07  8:39 ` Chandrabhanu Mahapatra
@ 2012-08-07  8:40   ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:28 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

OMAP4 checks are removed from VENC to provide it a cleaner interface. These
checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
"OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
from crashing OMAP4 kernel. An alternative approach is used to do the same in
later patches.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/venc.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..8fc165a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -752,11 +752,6 @@ static void venc_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
-	if (cpu_is_omap44xx()) {
-		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
-		return;
-	}
-
 	if (venc_runtime_get())
 		return;
 
@@ -971,16 +966,10 @@ static struct platform_driver omap_venchw_driver = {
 
 int __init venc_init_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return 0;
-
 	return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
 }
 
 void __exit venc_uninit_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return;
-
 	platform_driver_unregister(&omap_venchw_driver);
 }
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 5/6] ARM: OMAP: Disable venc for OMAP4
  2012-08-07  8:39 ` Chandrabhanu Mahapatra
  (?)
@ 2012-08-07  8:28   ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:28 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, linux-arm-kernel, Chandrabhanu Mahapatra

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 5/6] ARM: OMAP: Disable venc for OMAP4
@ 2012-08-07  8:28   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:28 UTC (permalink / raw)
  To: linux-arm-kernel

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks
  2012-08-07  8:39 ` Chandrabhanu Mahapatra
@ 2012-08-07  8:41   ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:29 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The OMAP3 checks have been removed and replaced by a dss feature
FEAT_DPI_USES_VDDS_DSI for cleaner implementation. The patches
"OMAP: DSS2: enable VDDS_DSI when using DPI" (8a2cfea8cc) by Tomi Valkeinen
<tomi.valkeinen@nokia.com> and "ARM: omap: fix oops in
drivers/video/omap2/dss/dpi.c" (4041071571) by Russell King
<rmk+kernel@arm.linux.org.uk> had introduced these checks. As it is evident
from these patches a dependency exists for some DSS pins on VDDS_DSI which is
better shown by dss feature FEAT_DPI_USES_VDDS_DSI.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dpi.c          |   12 +++++++-----
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 3266be2..b97f7b8 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -34,6 +34,7 @@
 #include <plat/cpu.h>
 
 #include "dss.h"
+#include "dss_features.h"
 
 static struct {
 	struct regulator *vdds_dsi_reg;
@@ -169,7 +170,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
 		return -ENODEV;
 	}
@@ -185,7 +186,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -229,7 +230,7 @@ err_dsi_pll_init:
 err_get_dsi:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
@@ -250,7 +251,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
@@ -329,7 +330,8 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+					dpi.vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 6b35200..ba70de5 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -373,6 +373,7 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
 	FEAT_ALPHA_FIXED_ZORDER,
 	FEAT_FIFO_MERGE,
 	FEAT_OMAP3_DSI_FIFO_BUG,
+	FEAT_DPI_USES_VDDS_DSI,
 };
 
 static const enum dss_feat_id omap3630_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index aa1e4b6..9c18fe3 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@ enum dss_feat_id {
 	FEAT_DSI_VC_OCP_WIDTH,
 	FEAT_DSI_REVERSE_TXCLKESC,
 	FEAT_DSI_GNQ,
+	FEAT_DPI_USES_VDDS_DSI,
 	FEAT_HDMI_CTS_SWMODE,
 	FEAT_HDMI_AUDIO_USE_MCLK,
 	FEAT_HANDLE_UV_SEPARATE,
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 0/6] OMAPDSS: Remove cpu_is checks
@ 2012-08-07  8:39 ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:39 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Hi everyone,
the patch series aims at cleaning up of DSS of cpu_is checks thereby making it
more generic.

The 1st patch cleans up cpu_is checks from DISPC code.
The 2nd patch removes unused functions from DSS code.
The 3rd patch cleans up cpu_is checks from DSS code.
The 4th patch removes cpu_is checks from VENC code.
The 5th patch disables VENC support on OMAP4.
The 6th patch removes cpu_is checks from DPI code and replaces it with a
dss feature.

All your comments and suggestions are welcome.

Regards,
Chandrabhanu

Chandrabhanu Mahapatra (6):
  OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  OMAPDSS: DSS: Remove redundant functions
  OMAPDSS: DSS: Remove cpu_is_xxxx checks
  OMAPDSS: VENC: Remove cpu_is_xxxx checks
  ARM: OMAP: Disable venc for OMAP4
  OMAPDSS: DPI: Remove cpu_is_xxxx checks

 arch/arm/mach-omap2/display.c          |    1 -
 drivers/video/omap2/dss/dispc.c        |  386 +++++++++++++++++++-------------
 drivers/video/omap2/dss/dpi.c          |   12 +-
 drivers/video/omap2/dss/dss.c          |  155 +++++++------
 drivers/video/omap2/dss/dss.h          |   73 +++++-
 drivers/video/omap2/dss/dss_features.c |   83 +++++++
 drivers/video/omap2/dss/dss_features.h |    4 +
 drivers/video/omap2/dss/venc.c         |   11 -
 8 files changed, 465 insertions(+), 260 deletions(-)

-- 
1.7.10


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07  8:39   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:39 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The cpu_is checks have been removed from DISPC providing it a much generic and
cleaner interface. The OMAP version and revision specific functions are
initialized by dispc_ops structure in dss features.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c        |  386 +++++++++++++++++++-------------
 drivers/video/omap2/dss/dss.h          |   48 ++++
 drivers/video/omap2/dss/dss_features.c |   42 ++++
 drivers/video/omap2/dss/dss_features.h |    2 +
 4 files changed, 317 insertions(+), 161 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..ad63302 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -101,6 +101,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_ops *ops;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1941,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1971,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.ops->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.ops->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
 	}
+	return 0;
+}
+
+int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth +				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.ops->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2139,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth -				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width = out_width && height = out_height)
 		return 0;
@@ -2017,118 +2165,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.ops->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2601,27 +2648,28 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 		height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT);
 }
 
-static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
+bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > 64 ||
+			hfp < 1 || hfp > 256 ||
+			hbp < 1 || hbp > 256 ||
+			vsw < 1 || vsw > 64  ||
+			vfp < 0 || vfp > 255 ||
+			vbp < 0 || vbp > 255)
+		return false;
+	return true;
+}
+bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp)
+{
+	if (hsw < 1 || hsw > 256 ||
+			hfp < 1  || hfp > 4096 ||
+			hbp < 1  || hbp > 4096 ||
+			vsw < 1  || vsw > 256  ||
+			vfp < 0  || vfp > 4095 ||
+			vbp < 0  || vbp > 4095)
+		return false;
 	return true;
 }
 
@@ -2633,7 +2681,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
 
 	if (dss_mgr_is_lcd(channel))
-		timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
+		timings_ok =  timings_ok &&
+			dispc.ops->lcd_timings_ok(timings->hsw,
 						timings->hfp, timings->hbp,
 						timings->vsw, timings->vfp,
 						timings->vbp);
@@ -2641,6 +2690,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	return timings_ok;
 }
 
+void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
+			FLD_VAL(hbp-1, 27, 20);
+	timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
+			FLD_VAL(vbp, 27, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
+void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
+			FLD_VAL(hbp-1, 31, 20);
+	timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
+			FLD_VAL(vbp, 31, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
 static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		int hfp, int hbp, int vsw, int vfp, int vbp,
 		enum omap_dss_signal_level vsync_level,
@@ -2650,25 +2727,10 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		enum omap_dss_signal_edge sync_pclk_edge)
 
 {
-	u32 timing_h, timing_v, l;
+	u32 l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
-
-	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
-	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+	dispc.ops->set_lcd_timings_hv(channel, hsw, hfp, hbp, vsw, vfp, vbp);
 
 	switch (data_pclk_edge) {
 	case OMAPDSS_DRIVE_SIG_RISING_EDGE:
@@ -3725,6 +3787,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	dispc_init_ops(dispc.ops);
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f67afe7..d87b885 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -171,6 +171,21 @@ struct dss_lcd_mgr_config {
 	int lcden_sig_polarity;
 };
 
+struct dispc_ops {
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+	bool (*lcd_timings_ok) (int hsw, int hfp, int hbp,
+			int vsw, int vfp, int vbp);
+	void (*set_lcd_timings_hv) (enum omap_channel channel, int hsw, int hfp,
+			int hbp, int vsw, int vfp, int vbp);
+};
+
 struct seq_file;
 struct platform_device;
 
@@ -457,6 +472,39 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
 void dispc_mgr_setup(enum omap_channel channel,
 		struct omap_overlay_manager_info *info);
 
+int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+
+unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+
+bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+
+void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp);
+void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel, int hsw,
+		int hfp, int hbp, int vsw, int vfp, int vbp);
+
 /* VENC */
 #ifdef CONFIG_OMAP2_DSS_VENC
 int venc_init_platform_driver(void) __init;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..b8d5095 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -567,6 +567,48 @@ static const struct omap_dss_features omap4_dss_features = {
 	.burst_size_unit = 16,
 };
 
+static const struct dispc_ops omap2_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_ops omap3_2_1_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_ops omap3_3_0_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
+static const struct dispc_ops omap4_dispc_ops = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
+void dispc_init_ops(const struct dispc_ops *ops)
+{
+	if (cpu_is_omap24xx()) {
+		ops = &omap2_dispc_ops;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			ops = &omap3_2_1_dispc_ops;
+		else
+			ops = &omap3_3_0_dispc_ops;
+	} else {
+		ops = &omap4_dispc_ops;
+	}
+}
+
 #if defined(CONFIG_OMAP4_DSS_HDMI)
 /* HDMI OMAP4 Functions*/
 static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..d03777a 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -120,4 +120,6 @@ void dss_features_init(void);
 #if defined(CONFIG_OMAP4_DSS_HDMI)
 void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
 #endif
+
+void dispc_init_ops(const struct dispc_ops *ops);
 #endif
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 2/6] OMAPDSS: DSS: Remove redundant functions
@ 2012-08-07  8:39   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:39 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Functions dss_calc_clock_rates() and dss_get_clock_div() are removed as these
functions have become redundant and no longer used.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |   45 -----------------------------------------
 drivers/video/omap2/dss/dss.h |    2 --
 2 files changed, 47 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 04b4586..7b1c6ac 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 	}
 }
 
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-		u16 fck_div_max = 16;
-
-		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));
-
-		cinfo->fck = prate / cinfo->fck_div;
-	} else {
-		if (cinfo->fck_div != 0)
-			return -EINVAL;
-		cinfo->fck = clk_get_rate(dss.dss_clk);
-	}
-
-	return 0;
-}
-
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
 	if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
 	return 0;
 }
 
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
-	cinfo->fck = clk_get_rate(dss.dss_clk);
-
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			cinfo->fck_div = prate / (cinfo->fck);
-		else
-			cinfo->fck_div = prate / (cinfo->fck / 2);
-	} else {
-		cinfo->fck_div = 0;
-	}
-
-	return 0;
-}
-
 unsigned long dss_get_dpll4_rate(void)
 {
 	if (dss.dpll4_m4_ck)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d87b885..5773c86 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -311,9 +311,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 3/6] OMAPDSS: DSS: Remove cpu_is_xxxx checks
@ 2012-08-07  8:40   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The cpu_is checks have been removed from dss.c providing it a much generic and
cleaner interface. The OMAP version and revision specific functions are
initialized by dss_ops structure in dss features.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c          |  114 ++++++++++++++++++++++----------
 drivers/video/omap2/dss/dss.h          |   23 ++++++-
 drivers/video/omap2/dss/dss_features.c |   40 +++++++++++
 drivers/video/omap2/dss/dss_features.h |    1 +
 4 files changed, 141 insertions(+), 37 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..c263da7 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -83,6 +83,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_ops *ops;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -236,6 +238,15 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
 	return dss_generic_clk_source_names[clk_src];
 }
 
+char *set_dump_clk_str_24_34(void)
+{
+	return "%s (%s) = %lu / %lu * 2  = %lu\n";
+}
+
+char *set_dump_clk_str(void)
+{
+	return "%s (%s) = %lu / %lu  = %lu\n";
+}
 
 void dss_dump_clocks(struct seq_file *s)
 {
@@ -254,23 +265,15 @@ void dss_dump_clocks(struct seq_file *s)
 	fclk_rate = clk_get_rate(dss.dss_clk);
 
 	if (dss.dpll4_m4_ck) {
+		char *str = dss.ops->set_str();
+
 		dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
 		dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, str, fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -461,6 +464,35 @@ unsigned long dss_get_dpll4_rate(void)
 		return 0;
 }
 
+u16 get_dss_fck_div_max_24_34(void)
+{
+	return 16;
+}
+
+u16 get_dss_fck_div_max(void)
+{
+	return 32;
+}
+
+bool set_dss_clock_info_34xx(void)
+{
+	unsigned long prate = dss_get_dpll4_rate();
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (prate = dss.cache_prate || dss.cache_dss_cinfo.fck = fck)
+		return true;
+	return false;
+}
+
+bool set_dss_clock_info(void)
+{
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (dss.cache_dss_cinfo.fck = fck)
+		return true;
+	return false;
+}
+
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo)
 {
@@ -470,7 +502,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div, fck_div_max;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -479,10 +511,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
-	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck = dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate = dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck = fck)) {
+	if (req_pck = dss.cache_req_pck && dss.ops->set_dss_cinfo()) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,8 +548,7 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
+		fck_div_max = dss.ops->get_fck_div_max();
 
 		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
@@ -619,6 +647,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
 	return REG_GET(DSS_CONTROL, 15, 15);
 }
 
+int dss_get_clk_24xx(struct clk *clk)
+{
+	clk = NULL;
+	return true;
+}
+
+int dss_get_clk_3xxx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll4_m4_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll4_m4_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
+int dss_get_clk_44xx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll_per_m5x2_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll_per_m5x2_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
 static int dss_get_clocks(void)
 {
 	struct clk *clk;
@@ -633,23 +687,9 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
-	}
+	r = dss.ops->get_clk(clk);
+	if (r != true)
+		goto err;
 
 	dss.dpll4_m4_ck = clk;
 
@@ -750,6 +790,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	dss_init_ops(dss.ops);
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5773c86..b756ae1 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -19,7 +19,6 @@
  * You should have received a copy of the GNU General Public License along with
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
 #ifndef __OMAP2_DSS_H
 #define __OMAP2_DSS_H
 
@@ -186,6 +185,15 @@ struct dispc_ops {
 			int hbp, int vsw, int vfp, int vbp);
 };
 
+struct clk;
+
+struct dss_ops {
+	u16 (*get_fck_div_max) (void);
+	bool (*set_dss_cinfo) (void);
+	int (*get_clk) (struct clk *clk);
+	char *(*set_str) (void);
+};
+
 struct seq_file;
 struct platform_device;
 
@@ -315,6 +323,19 @@ int dss_set_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
+u16 get_dss_fck_div_max_24_34(void);
+u16 get_dss_fck_div_max(void);
+
+bool set_dss_clock_info(void);
+bool set_dss_clock_info_34xx(void);
+
+int dss_get_clk_24xx(struct clk *clk);
+int dss_get_clk_3xxx(struct clk *clk);
+int dss_get_clk_44xx(struct clk *clk);
+
+char *set_dump_clk_str_24_34(void);
+char *set_dump_clk_str(void);
+
 /* SDI */
 int sdi_init_platform_driver(void) __init;
 void sdi_uninit_platform_driver(void) __exit;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index b8d5095..6b35200 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -609,6 +609,46 @@ void dispc_init_ops(const struct dispc_ops *ops)
 	}
 }
 
+static const struct dss_ops omap2_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
+	.set_dss_cinfo		=	set_dss_clock_info,
+	.get_clk		=	dss_get_clk_24xx,
+	.set_str		=	set_dump_clk_str_24_34,
+};
+
+static const struct dss_ops omap34_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
+	.set_dss_cinfo		=	set_dss_clock_info_34xx,
+	.get_clk		=	dss_get_clk_3xxx,
+	.set_str		=	set_dump_clk_str_24_34,
+};
+
+static const struct dss_ops omap36_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max,
+	.set_dss_cinfo		=	set_dss_clock_info,
+	.get_clk		=	dss_get_clk_3xxx,
+	.set_str		=	set_dump_clk_str,
+};
+
+static const struct dss_ops omap4_dss_ops = {
+	.get_fck_div_max	=	get_dss_fck_div_max,
+	.set_dss_cinfo		=	set_dss_clock_info,
+	.get_clk		=	dss_get_clk_44xx,
+	.set_str		=	set_dump_clk_str,
+};
+
+void dss_init_ops(const struct dss_ops *ops)
+{
+	if (cpu_is_omap24xx())
+		ops = &omap2_dss_ops;
+	else if (cpu_is_omap34xx())
+		ops = &omap34_dss_ops;
+	else if (cpu_is_omap3630())
+		ops = &omap36_dss_ops;
+	else
+		ops = &omap4_dss_ops;
+}
+
 #if defined(CONFIG_OMAP4_DSS_HDMI)
 /* HDMI OMAP4 Functions*/
 static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index d03777a..aa1e4b6 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -122,4 +122,5 @@ void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
 #endif
 
 void dispc_init_ops(const struct dispc_ops *ops);
+void dss_init_ops(const struct dss_ops *ops);
 #endif
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
@ 2012-08-07  8:40   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

OMAP4 checks are removed from VENC to provide it a cleaner interface. These
checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
"OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
from crashing OMAP4 kernel. An alternative approach is used to do the same in
later patches.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/venc.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..8fc165a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -752,11 +752,6 @@ static void venc_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
-	if (cpu_is_omap44xx()) {
-		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
-		return;
-	}
-
 	if (venc_runtime_get())
 		return;
 
@@ -971,16 +966,10 @@ static struct platform_driver omap_venchw_driver = {
 
 int __init venc_init_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return 0;
-
 	return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
 }
 
 void __exit venc_uninit_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return;
-
 	platform_driver_unregister(&omap_venchw_driver);
 }
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 5/6] ARM: OMAP: Disable venc for OMAP4
@ 2012-08-07  8:28   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks
@ 2012-08-07  8:41   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07  8:41 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The OMAP3 checks have been removed and replaced by a dss feature
FEAT_DPI_USES_VDDS_DSI for cleaner implementation. The patches
"OMAP: DSS2: enable VDDS_DSI when using DPI" (8a2cfea8cc) by Tomi Valkeinen
<tomi.valkeinen@nokia.com> and "ARM: omap: fix oops in
drivers/video/omap2/dss/dpi.c" (4041071571) by Russell King
<rmk+kernel@arm.linux.org.uk> had introduced these checks. As it is evident
from these patches a dependency exists for some DSS pins on VDDS_DSI which is
better shown by dss feature FEAT_DPI_USES_VDDS_DSI.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dpi.c          |   12 +++++++-----
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 3266be2..b97f7b8 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -34,6 +34,7 @@
 #include <plat/cpu.h>
 
 #include "dss.h"
+#include "dss_features.h"
 
 static struct {
 	struct regulator *vdds_dsi_reg;
@@ -169,7 +170,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
 		return -ENODEV;
 	}
@@ -185,7 +186,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -229,7 +230,7 @@ err_dsi_pll_init:
 err_get_dsi:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
@@ -250,7 +251,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
@@ -329,7 +330,8 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg = NULL) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+					dpi.vdds_dsi_reg = NULL) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 6b35200..ba70de5 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -373,6 +373,7 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
 	FEAT_ALPHA_FIXED_ZORDER,
 	FEAT_FIFO_MERGE,
 	FEAT_OMAP3_DSI_FIFO_BUG,
+	FEAT_DPI_USES_VDDS_DSI,
 };
 
 static const enum dss_feat_id omap3630_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index aa1e4b6..9c18fe3 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@ enum dss_feat_id {
 	FEAT_DSI_VC_OCP_WIDTH,
 	FEAT_DSI_REVERSE_TXCLKESC,
 	FEAT_DSI_GNQ,
+	FEAT_DPI_USES_VDDS_DSI,
 	FEAT_HDMI_CTS_SWMODE,
 	FEAT_HDMI_AUDIO_USE_MCLK,
 	FEAT_HANDLE_UV_SEPARATE,
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  8:39   ` Chandrabhanu Mahapatra
@ 2012-08-07  8:48     ` Felipe Balbi
  -1 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  8:48 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2078 bytes --]

Hi,

On Tue, Aug 07, 2012 at 01:57:42PM +0530, Chandrabhanu Mahapatra wrote:
> diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
> index 9387097..b8d5095 100644
> --- a/drivers/video/omap2/dss/dss_features.c
> +++ b/drivers/video/omap2/dss/dss_features.c
> @@ -567,6 +567,48 @@ static const struct omap_dss_features omap4_dss_features = {
>  	.burst_size_unit = 16,
>  };
>  
> +static const struct dispc_ops omap2_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
> +	.calc_core_clk		=	calc_core_clk_24xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_ops omap3_2_1_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_ops omap3_3_0_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};
> +
> +static const struct dispc_ops omap4_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
> +	.calc_core_clk		=	calc_core_clk_44xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};
> +
> +void dispc_init_ops(const struct dispc_ops *ops)
> +{
> +	if (cpu_is_omap24xx()) {
> +		ops = &omap2_dispc_ops;
> +	} else if (cpu_is_omap34xx()) {
> +		if (omap_rev() < OMAP3430_REV_ES3_0)
> +			ops = &omap3_2_1_dispc_ops;
> +		else
> +			ops = &omap3_3_0_dispc_ops;
> +	} else {
> +		ops = &omap4_dispc_ops;
> +	}
> +}

you're not really removing. You're moving cpu_is_* somewhere else. A
better approach, IMHO, would be to use the DSS_REVISION register to
differentiate the DSS IP itself, not the OMAP.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07  8:48     ` Felipe Balbi
  0 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  8:48 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2078 bytes --]

Hi,

On Tue, Aug 07, 2012 at 01:57:42PM +0530, Chandrabhanu Mahapatra wrote:
> diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
> index 9387097..b8d5095 100644
> --- a/drivers/video/omap2/dss/dss_features.c
> +++ b/drivers/video/omap2/dss/dss_features.c
> @@ -567,6 +567,48 @@ static const struct omap_dss_features omap4_dss_features = {
>  	.burst_size_unit = 16,
>  };
>  
> +static const struct dispc_ops omap2_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
> +	.calc_core_clk		=	calc_core_clk_24xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_ops omap3_2_1_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_ops omap3_3_0_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};
> +
> +static const struct dispc_ops omap4_dispc_ops = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
> +	.calc_core_clk		=	calc_core_clk_44xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};
> +
> +void dispc_init_ops(const struct dispc_ops *ops)
> +{
> +	if (cpu_is_omap24xx()) {
> +		ops = &omap2_dispc_ops;
> +	} else if (cpu_is_omap34xx()) {
> +		if (omap_rev() < OMAP3430_REV_ES3_0)
> +			ops = &omap3_2_1_dispc_ops;
> +		else
> +			ops = &omap3_3_0_dispc_ops;
> +	} else {
> +		ops = &omap4_dispc_ops;
> +	}
> +}

you're not really removing. You're moving cpu_is_* somewhere else. A
better approach, IMHO, would be to use the DSS_REVISION register to
differentiate the DSS IP itself, not the OMAP.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Remove cpu_is_xxxx checks
  2012-08-07  8:40   ` Chandrabhanu Mahapatra
@ 2012-08-07  8:49     ` Felipe Balbi
  -1 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  8:49 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 9409 bytes --]

On Tue, Aug 07, 2012 at 01:58:04PM +0530, Chandrabhanu Mahapatra wrote:
> The cpu_is checks have been removed from dss.c providing it a much generic and
> cleaner interface. The OMAP version and revision specific functions are
> initialized by dss_ops structure in dss features.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c          |  114 ++++++++++++++++++++++----------
>  drivers/video/omap2/dss/dss.h          |   23 ++++++-
>  drivers/video/omap2/dss/dss_features.c |   40 +++++++++++
>  drivers/video/omap2/dss/dss_features.h |    1 +
>  4 files changed, 141 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..c263da7 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -83,6 +83,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_ops *ops;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -236,6 +238,15 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> +char *set_dump_clk_str_24_34(void)
> +{
> +	return "%s (%s) = %lu / %lu * 2  = %lu\n";
> +}
> +
> +char *set_dump_clk_str(void)
> +{
> +	return "%s (%s) = %lu / %lu  = %lu\n";
> +}
>  
>  void dss_dump_clocks(struct seq_file *s)
>  {
> @@ -254,23 +265,15 @@ void dss_dump_clocks(struct seq_file *s)
>  	fclk_rate = clk_get_rate(dss.dss_clk);
>  
>  	if (dss.dpll4_m4_ck) {
> +		char *str = dss.ops->set_str();
> +
>  		dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
>  		dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
>  
>  		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>  
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> -		else
> -			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> +		seq_printf(s, str, fclk_name, fclk_real_name, dpll4_ck_rate,
> +				dpll4_ck_rate / dpll4_m4_ck_rate, fclk_rate);
>  	} else {
>  		seq_printf(s, "%s (%s) = %lu\n",
>  				fclk_name, fclk_real_name,
> @@ -461,6 +464,35 @@ unsigned long dss_get_dpll4_rate(void)
>  		return 0;
>  }
>  
> +u16 get_dss_fck_div_max_24_34(void)
> +{
> +	return 16;
> +}
> +
> +u16 get_dss_fck_div_max(void)
> +{
> +	return 32;
> +}
> +
> +bool set_dss_clock_info_34xx(void)
> +{
> +	unsigned long prate = dss_get_dpll4_rate();
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (prate == dss.cache_prate || dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;
> +}
> +
> +bool set_dss_clock_info(void)
> +{
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;
> +}
> +
>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  		struct dispc_clock_info *dispc_cinfo)
>  {
> @@ -470,7 +502,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	unsigned long fck, max_dss_fck;
>  
> -	u16 fck_div, fck_div_max = 16;
> +	u16 fck_div, fck_div_max;
>  
>  	int match = 0;
>  	int min_fck_per_pck;
> @@ -479,10 +511,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
> -	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && dss.ops->set_dss_cinfo()) {
>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;
> @@ -519,8 +548,7 @@ retry:
>  
>  		goto found;
>  	} else {
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			fck_div_max = 32;
> +		fck_div_max = dss.ops->get_fck_div_max();
>  
>  		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
>  			struct dispc_clock_info cur_dispc;
> @@ -619,6 +647,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
>  	return REG_GET(DSS_CONTROL, 15, 15);
>  }
>  
> +int dss_get_clk_24xx(struct clk *clk)
> +{
> +	clk = NULL;
> +	return true;
> +}
> +
> +int dss_get_clk_3xxx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll4_m4_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll4_m4_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}
> +
> +int dss_get_clk_44xx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll_per_m5x2_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll_per_m5x2_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}
> +
>  static int dss_get_clocks(void)
>  {
>  	struct clk *clk;
> @@ -633,23 +687,9 @@ static int dss_get_clocks(void)
>  
>  	dss.dss_clk = clk;
>  
> -	if (cpu_is_omap34xx()) {
> -		clk = clk_get(NULL, "dpll4_m4_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll4_m4_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else if (cpu_is_omap44xx()) {
> -		clk = clk_get(NULL, "dpll_per_m5x2_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll_per_m5x2_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else { /* omap24xx */
> -		clk = NULL;
> -	}
> +	r = dss.ops->get_clk(clk);
> +	if (r != true)
> +		goto err;
>  
>  	dss.dpll4_m4_ck = clk;
>  
> @@ -750,6 +790,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
>  	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
>  	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
>  
> +	dss_init_ops(dss.ops);
> +
>  	rev = dss_read_reg(DSS_REVISION);
>  	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
>  			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 5773c86..b756ae1 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -19,7 +19,6 @@
>   * You should have received a copy of the GNU General Public License along with
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
> -
>  #ifndef __OMAP2_DSS_H
>  #define __OMAP2_DSS_H
>  
> @@ -186,6 +185,15 @@ struct dispc_ops {
>  			int hbp, int vsw, int vfp, int vbp);
>  };
>  
> +struct clk;
> +
> +struct dss_ops {
> +	u16 (*get_fck_div_max) (void);
> +	bool (*set_dss_cinfo) (void);
> +	int (*get_clk) (struct clk *clk);
> +	char *(*set_str) (void);
> +};
> +
>  struct seq_file;
>  struct platform_device;
>  
> @@ -315,6 +323,19 @@ int dss_set_clock_div(struct dss_clock_info *cinfo);
>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  		struct dispc_clock_info *dispc_cinfo);
>  
> +u16 get_dss_fck_div_max_24_34(void);
> +u16 get_dss_fck_div_max(void);
> +
> +bool set_dss_clock_info(void);
> +bool set_dss_clock_info_34xx(void);
> +
> +int dss_get_clk_24xx(struct clk *clk);
> +int dss_get_clk_3xxx(struct clk *clk);
> +int dss_get_clk_44xx(struct clk *clk);
> +
> +char *set_dump_clk_str_24_34(void);
> +char *set_dump_clk_str(void);
> +
>  /* SDI */
>  int sdi_init_platform_driver(void) __init;
>  void sdi_uninit_platform_driver(void) __exit;
> diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
> index b8d5095..6b35200 100644
> --- a/drivers/video/omap2/dss/dss_features.c
> +++ b/drivers/video/omap2/dss/dss_features.c
> @@ -609,6 +609,46 @@ void dispc_init_ops(const struct dispc_ops *ops)
>  	}
>  }
>  
> +static const struct dss_ops omap2_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
> +	.set_dss_cinfo		=	set_dss_clock_info,
> +	.get_clk		=	dss_get_clk_24xx,
> +	.set_str		=	set_dump_clk_str_24_34,
> +};
> +
> +static const struct dss_ops omap34_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
> +	.set_dss_cinfo		=	set_dss_clock_info_34xx,
> +	.get_clk		=	dss_get_clk_3xxx,
> +	.set_str		=	set_dump_clk_str_24_34,
> +};
> +
> +static const struct dss_ops omap36_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max,
> +	.set_dss_cinfo		=	set_dss_clock_info,
> +	.get_clk		=	dss_get_clk_3xxx,
> +	.set_str		=	set_dump_clk_str,
> +};
> +
> +static const struct dss_ops omap4_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max,
> +	.set_dss_cinfo		=	set_dss_clock_info,
> +	.get_clk		=	dss_get_clk_44xx,
> +	.set_str		=	set_dump_clk_str,
> +};
> +
> +void dss_init_ops(const struct dss_ops *ops)
> +{
> +	if (cpu_is_omap24xx())
> +		ops = &omap2_dss_ops;
> +	else if (cpu_is_omap34xx())
> +		ops = &omap34_dss_ops;
> +	else if (cpu_is_omap3630())
> +		ops = &omap36_dss_ops;
> +	else
> +		ops = &omap4_dss_ops;
> +}

same comment as previous patch. Just moving the checks somewhere else
and creating even more indirection through function pointers, when you
could just do the runtime DSS IP revision check.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Remove cpu_is_xxxx checks
@ 2012-08-07  8:49     ` Felipe Balbi
  0 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  8:49 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 9409 bytes --]

On Tue, Aug 07, 2012 at 01:58:04PM +0530, Chandrabhanu Mahapatra wrote:
> The cpu_is checks have been removed from dss.c providing it a much generic and
> cleaner interface. The OMAP version and revision specific functions are
> initialized by dss_ops structure in dss features.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c          |  114 ++++++++++++++++++++++----------
>  drivers/video/omap2/dss/dss.h          |   23 ++++++-
>  drivers/video/omap2/dss/dss_features.c |   40 +++++++++++
>  drivers/video/omap2/dss/dss_features.h |    1 +
>  4 files changed, 141 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..c263da7 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -83,6 +83,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_ops *ops;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -236,6 +238,15 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> +char *set_dump_clk_str_24_34(void)
> +{
> +	return "%s (%s) = %lu / %lu * 2  = %lu\n";
> +}
> +
> +char *set_dump_clk_str(void)
> +{
> +	return "%s (%s) = %lu / %lu  = %lu\n";
> +}
>  
>  void dss_dump_clocks(struct seq_file *s)
>  {
> @@ -254,23 +265,15 @@ void dss_dump_clocks(struct seq_file *s)
>  	fclk_rate = clk_get_rate(dss.dss_clk);
>  
>  	if (dss.dpll4_m4_ck) {
> +		char *str = dss.ops->set_str();
> +
>  		dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
>  		dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
>  
>  		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>  
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> -		else
> -			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> +		seq_printf(s, str, fclk_name, fclk_real_name, dpll4_ck_rate,
> +				dpll4_ck_rate / dpll4_m4_ck_rate, fclk_rate);
>  	} else {
>  		seq_printf(s, "%s (%s) = %lu\n",
>  				fclk_name, fclk_real_name,
> @@ -461,6 +464,35 @@ unsigned long dss_get_dpll4_rate(void)
>  		return 0;
>  }
>  
> +u16 get_dss_fck_div_max_24_34(void)
> +{
> +	return 16;
> +}
> +
> +u16 get_dss_fck_div_max(void)
> +{
> +	return 32;
> +}
> +
> +bool set_dss_clock_info_34xx(void)
> +{
> +	unsigned long prate = dss_get_dpll4_rate();
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (prate == dss.cache_prate || dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;
> +}
> +
> +bool set_dss_clock_info(void)
> +{
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;
> +}
> +
>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  		struct dispc_clock_info *dispc_cinfo)
>  {
> @@ -470,7 +502,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	unsigned long fck, max_dss_fck;
>  
> -	u16 fck_div, fck_div_max = 16;
> +	u16 fck_div, fck_div_max;
>  
>  	int match = 0;
>  	int min_fck_per_pck;
> @@ -479,10 +511,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
> -	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && dss.ops->set_dss_cinfo()) {
>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;
> @@ -519,8 +548,7 @@ retry:
>  
>  		goto found;
>  	} else {
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			fck_div_max = 32;
> +		fck_div_max = dss.ops->get_fck_div_max();
>  
>  		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
>  			struct dispc_clock_info cur_dispc;
> @@ -619,6 +647,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
>  	return REG_GET(DSS_CONTROL, 15, 15);
>  }
>  
> +int dss_get_clk_24xx(struct clk *clk)
> +{
> +	clk = NULL;
> +	return true;
> +}
> +
> +int dss_get_clk_3xxx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll4_m4_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll4_m4_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}
> +
> +int dss_get_clk_44xx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll_per_m5x2_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll_per_m5x2_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}
> +
>  static int dss_get_clocks(void)
>  {
>  	struct clk *clk;
> @@ -633,23 +687,9 @@ static int dss_get_clocks(void)
>  
>  	dss.dss_clk = clk;
>  
> -	if (cpu_is_omap34xx()) {
> -		clk = clk_get(NULL, "dpll4_m4_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll4_m4_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else if (cpu_is_omap44xx()) {
> -		clk = clk_get(NULL, "dpll_per_m5x2_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll_per_m5x2_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else { /* omap24xx */
> -		clk = NULL;
> -	}
> +	r = dss.ops->get_clk(clk);
> +	if (r != true)
> +		goto err;
>  
>  	dss.dpll4_m4_ck = clk;
>  
> @@ -750,6 +790,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
>  	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
>  	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
>  
> +	dss_init_ops(dss.ops);
> +
>  	rev = dss_read_reg(DSS_REVISION);
>  	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
>  			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 5773c86..b756ae1 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -19,7 +19,6 @@
>   * You should have received a copy of the GNU General Public License along with
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
> -
>  #ifndef __OMAP2_DSS_H
>  #define __OMAP2_DSS_H
>  
> @@ -186,6 +185,15 @@ struct dispc_ops {
>  			int hbp, int vsw, int vfp, int vbp);
>  };
>  
> +struct clk;
> +
> +struct dss_ops {
> +	u16 (*get_fck_div_max) (void);
> +	bool (*set_dss_cinfo) (void);
> +	int (*get_clk) (struct clk *clk);
> +	char *(*set_str) (void);
> +};
> +
>  struct seq_file;
>  struct platform_device;
>  
> @@ -315,6 +323,19 @@ int dss_set_clock_div(struct dss_clock_info *cinfo);
>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  		struct dispc_clock_info *dispc_cinfo);
>  
> +u16 get_dss_fck_div_max_24_34(void);
> +u16 get_dss_fck_div_max(void);
> +
> +bool set_dss_clock_info(void);
> +bool set_dss_clock_info_34xx(void);
> +
> +int dss_get_clk_24xx(struct clk *clk);
> +int dss_get_clk_3xxx(struct clk *clk);
> +int dss_get_clk_44xx(struct clk *clk);
> +
> +char *set_dump_clk_str_24_34(void);
> +char *set_dump_clk_str(void);
> +
>  /* SDI */
>  int sdi_init_platform_driver(void) __init;
>  void sdi_uninit_platform_driver(void) __exit;
> diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
> index b8d5095..6b35200 100644
> --- a/drivers/video/omap2/dss/dss_features.c
> +++ b/drivers/video/omap2/dss/dss_features.c
> @@ -609,6 +609,46 @@ void dispc_init_ops(const struct dispc_ops *ops)
>  	}
>  }
>  
> +static const struct dss_ops omap2_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
> +	.set_dss_cinfo		=	set_dss_clock_info,
> +	.get_clk		=	dss_get_clk_24xx,
> +	.set_str		=	set_dump_clk_str_24_34,
> +};
> +
> +static const struct dss_ops omap34_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max_24_34,
> +	.set_dss_cinfo		=	set_dss_clock_info_34xx,
> +	.get_clk		=	dss_get_clk_3xxx,
> +	.set_str		=	set_dump_clk_str_24_34,
> +};
> +
> +static const struct dss_ops omap36_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max,
> +	.set_dss_cinfo		=	set_dss_clock_info,
> +	.get_clk		=	dss_get_clk_3xxx,
> +	.set_str		=	set_dump_clk_str,
> +};
> +
> +static const struct dss_ops omap4_dss_ops = {
> +	.get_fck_div_max	=	get_dss_fck_div_max,
> +	.set_dss_cinfo		=	set_dss_clock_info,
> +	.get_clk		=	dss_get_clk_44xx,
> +	.set_str		=	set_dump_clk_str,
> +};
> +
> +void dss_init_ops(const struct dss_ops *ops)
> +{
> +	if (cpu_is_omap24xx())
> +		ops = &omap2_dss_ops;
> +	else if (cpu_is_omap34xx())
> +		ops = &omap34_dss_ops;
> +	else if (cpu_is_omap3630())
> +		ops = &omap36_dss_ops;
> +	else
> +		ops = &omap4_dss_ops;
> +}

same comment as previous patch. Just moving the checks somewhere else
and creating even more indirection through function pointers, when you
could just do the runtime DSS IP revision check.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
  2012-08-07  8:40   ` Chandrabhanu Mahapatra
@ 2012-08-07  8:51     ` Felipe Balbi
  -1 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  8:51 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 703 bytes --]

On Tue, Aug 07, 2012 at 01:58:17PM +0530, Chandrabhanu Mahapatra wrote:
> OMAP4 checks are removed from VENC to provide it a cleaner interface. These
> checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
> to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
> "OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
> OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
> from crashing OMAP4 kernel. An alternative approach is used to do the same in
> later patches.

in later patches ? This means you're causing a regression here. Just
swap the patches around to avoid it.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
@ 2012-08-07  8:51     ` Felipe Balbi
  0 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  8:51 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 703 bytes --]

On Tue, Aug 07, 2012 at 01:58:17PM +0530, Chandrabhanu Mahapatra wrote:
> OMAP4 checks are removed from VENC to provide it a cleaner interface. These
> checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
> to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
> "OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
> OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
> from crashing OMAP4 kernel. An alternative approach is used to do the same in
> later patches.

in later patches ? This means you're causing a regression here. Just
swap the patches around to avoid it.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  8:48     ` Felipe Balbi
@ 2012-08-07  9:05       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07  9:05 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 674 bytes --]

On Tue, 2012-08-07 at 11:48 +0300, Felipe Balbi wrote:

> you're not really removing. You're moving cpu_is_* somewhere else. A
> better approach, IMHO, would be to use the DSS_REVISION register to
> differentiate the DSS IP itself, not the OMAP.

Unfortunately we can't, DSS_REVISION contains bogus information.

I didn't look at these patches yet, but the idea has been to move the
cpu_is_* checks to only a few central places, not scattered all over.

At some point we could perhaps either move the cpu_is_ check code to
somewhere under arch/arm, or, more probably, create our own DSS version
IDs which are found out via cpu_is or soc_is or such.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07  9:05       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07  9:05 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 674 bytes --]

On Tue, 2012-08-07 at 11:48 +0300, Felipe Balbi wrote:

> you're not really removing. You're moving cpu_is_* somewhere else. A
> better approach, IMHO, would be to use the DSS_REVISION register to
> differentiate the DSS IP itself, not the OMAP.

Unfortunately we can't, DSS_REVISION contains bogus information.

I didn't look at these patches yet, but the idea has been to move the
cpu_is_* checks to only a few central places, not scattered all over.

At some point we could perhaps either move the cpu_is_ check code to
somewhere under arch/arm, or, more probably, create our own DSS version
IDs which are found out via cpu_is or soc_is or such.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  9:05       ` Tomi Valkeinen
@ 2012-08-07  9:14         ` Felipe Balbi
  -1 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  9:14 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1526 bytes --]

On Tue, Aug 07, 2012 at 12:05:29PM +0300, Tomi Valkeinen wrote:
> On Tue, 2012-08-07 at 11:48 +0300, Felipe Balbi wrote:
> 
> > you're not really removing. You're moving cpu_is_* somewhere else. A
> > better approach, IMHO, would be to use the DSS_REVISION register to
> > differentiate the DSS IP itself, not the OMAP.
> 
> Unfortunately we can't, DSS_REVISION contains bogus information.
> 
> I didn't look at these patches yet, but the idea has been to move the
> cpu_is_* checks to only a few central places, not scattered all over.
> 
> At some point we could perhaps either move the cpu_is_ check code to
> somewhere under arch/arm, or, more probably, create our own DSS version
> IDs which are found out via cpu_is or soc_is or such.

Or you could use the driver_data field on the platform_device_id and
of_device_id structures for that. Something like:

static const struct platform_device_id dss_id_table[] __initconst = {
{
	{ "omap2-dss", omap2_dss_features },
	{ "omap3-dss", omap3_dss_features },
	{ "omap4-dss", omap4_dss_features },
	{ "omap5-dss", omap5_dss_features },
	{} /* Terminating entry */
};

then, on your probe, you just need to copy id->driver_data to your own
structures so you can reference them later. No need for cpu_is_* or
soc_is_* or machine_is_* anywhere.

On your platform_code, wherever you create the dss device, you need to
fix up the name though. The platform_device name should match
platform_device_id name, not platform_driver name.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07  9:14         ` Felipe Balbi
  0 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  9:14 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1526 bytes --]

On Tue, Aug 07, 2012 at 12:05:29PM +0300, Tomi Valkeinen wrote:
> On Tue, 2012-08-07 at 11:48 +0300, Felipe Balbi wrote:
> 
> > you're not really removing. You're moving cpu_is_* somewhere else. A
> > better approach, IMHO, would be to use the DSS_REVISION register to
> > differentiate the DSS IP itself, not the OMAP.
> 
> Unfortunately we can't, DSS_REVISION contains bogus information.
> 
> I didn't look at these patches yet, but the idea has been to move the
> cpu_is_* checks to only a few central places, not scattered all over.
> 
> At some point we could perhaps either move the cpu_is_ check code to
> somewhere under arch/arm, or, more probably, create our own DSS version
> IDs which are found out via cpu_is or soc_is or such.

Or you could use the driver_data field on the platform_device_id and
of_device_id structures for that. Something like:

static const struct platform_device_id dss_id_table[] __initconst = {
{
	{ "omap2-dss", omap2_dss_features },
	{ "omap3-dss", omap3_dss_features },
	{ "omap4-dss", omap4_dss_features },
	{ "omap5-dss", omap5_dss_features },
	{} /* Terminating entry */
};

then, on your probe, you just need to copy id->driver_data to your own
structures so you can reference them later. No need for cpu_is_* or
soc_is_* or machine_is_* anywhere.

On your platform_code, wherever you create the dss device, you need to
fix up the name though. The platform_device name should match
platform_device_id name, not platform_driver name.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  9:14         ` Felipe Balbi
@ 2012-08-07  9:27           ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07  9:27 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1094 bytes --]

On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:

> Or you could use the driver_data field on the platform_device_id and
> of_device_id structures for that. Something like:
> 
> static const struct platform_device_id dss_id_table[] __initconst = {
> {
> 	{ "omap2-dss", omap2_dss_features },
> 	{ "omap3-dss", omap3_dss_features },
> 	{ "omap4-dss", omap4_dss_features },
> 	{ "omap5-dss", omap5_dss_features },
> 	{} /* Terminating entry */
> };
> 
> then, on your probe, you just need to copy id->driver_data to your own
> structures so you can reference them later. No need for cpu_is_* or
> soc_is_* or machine_is_* anywhere.
> 
> On your platform_code, wherever you create the dss device, you need to
> fix up the name though. The platform_device name should match
> platform_device_id name, not platform_driver name.

I've thought about that, but we need versions even for different OMAP ES
versions.

So in the device tree data we couldn't have the DSS nodes in a, say,
common omap4 file. We'd need separate DT files for each OMAP ES version.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07  9:27           ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07  9:27 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1094 bytes --]

On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:

> Or you could use the driver_data field on the platform_device_id and
> of_device_id structures for that. Something like:
> 
> static const struct platform_device_id dss_id_table[] __initconst = {
> {
> 	{ "omap2-dss", omap2_dss_features },
> 	{ "omap3-dss", omap3_dss_features },
> 	{ "omap4-dss", omap4_dss_features },
> 	{ "omap5-dss", omap5_dss_features },
> 	{} /* Terminating entry */
> };
> 
> then, on your probe, you just need to copy id->driver_data to your own
> structures so you can reference them later. No need for cpu_is_* or
> soc_is_* or machine_is_* anywhere.
> 
> On your platform_code, wherever you create the dss device, you need to
> fix up the name though. The platform_device name should match
> platform_device_id name, not platform_driver name.

I've thought about that, but we need versions even for different OMAP ES
versions.

So in the device tree data we couldn't have the DSS nodes in a, say,
common omap4 file. We'd need separate DT files for each OMAP ES version.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  9:27           ` Tomi Valkeinen
@ 2012-08-07  9:32             ` Felipe Balbi
  -1 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  9:32 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 1558 bytes --]

Hi,

On Tue, Aug 07, 2012 at 12:27:52PM +0300, Tomi Valkeinen wrote:
> On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:
> 
> > Or you could use the driver_data field on the platform_device_id and
> > of_device_id structures for that. Something like:
> > 
> > static const struct platform_device_id dss_id_table[] __initconst = {
> > {
> > 	{ "omap2-dss", omap2_dss_features },
> > 	{ "omap3-dss", omap3_dss_features },
> > 	{ "omap4-dss", omap4_dss_features },
> > 	{ "omap5-dss", omap5_dss_features },
> > 	{} /* Terminating entry */
> > };
> > 
> > then, on your probe, you just need to copy id->driver_data to your own
> > structures so you can reference them later. No need for cpu_is_* or
> > soc_is_* or machine_is_* anywhere.
> > 
> > On your platform_code, wherever you create the dss device, you need to
> > fix up the name though. The platform_device name should match
> > platform_device_id name, not platform_driver name.
> 
> I've thought about that, but we need versions even for different OMAP ES
> versions.
> 
> So in the device tree data we couldn't have the DSS nodes in a, say,
> common omap4 file. We'd need separate DT files for each OMAP ES version.

you can overwrite attributes on your board dts file, right ? Meaning
that e.g. omap4.dtsi would have:

dss1: dss@xxxx {
	compatible = "ti, omap4-dss";
};


then on omap4-based-board.dts:

&dss1 {
	compatible = "ti,omap4-based-board-dss";
};

or something similar. Isn't that doable ? Benoit, would this work on
DTS ?

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07  9:32             ` Felipe Balbi
  0 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07  9:32 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 1558 bytes --]

Hi,

On Tue, Aug 07, 2012 at 12:27:52PM +0300, Tomi Valkeinen wrote:
> On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:
> 
> > Or you could use the driver_data field on the platform_device_id and
> > of_device_id structures for that. Something like:
> > 
> > static const struct platform_device_id dss_id_table[] __initconst = {
> > {
> > 	{ "omap2-dss", omap2_dss_features },
> > 	{ "omap3-dss", omap3_dss_features },
> > 	{ "omap4-dss", omap4_dss_features },
> > 	{ "omap5-dss", omap5_dss_features },
> > 	{} /* Terminating entry */
> > };
> > 
> > then, on your probe, you just need to copy id->driver_data to your own
> > structures so you can reference them later. No need for cpu_is_* or
> > soc_is_* or machine_is_* anywhere.
> > 
> > On your platform_code, wherever you create the dss device, you need to
> > fix up the name though. The platform_device name should match
> > platform_device_id name, not platform_driver name.
> 
> I've thought about that, but we need versions even for different OMAP ES
> versions.
> 
> So in the device tree data we couldn't have the DSS nodes in a, say,
> common omap4 file. We'd need separate DT files for each OMAP ES version.

you can overwrite attributes on your board dts file, right ? Meaning
that e.g. omap4.dtsi would have:

dss1: dss@xxxx {
	compatible = "ti, omap4-dss";
};


then on omap4-based-board.dts:

&dss1 {
	compatible = "ti,omap4-based-board-dss";
};

or something similar. Isn't that doable ? Benoit, would this work on
DTS ?

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  9:32             ` Felipe Balbi
@ 2012-08-07  9:57               ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07  9:57 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 2182 bytes --]

On Tue, 2012-08-07 at 12:32 +0300, Felipe Balbi wrote:
> Hi,
> 
> On Tue, Aug 07, 2012 at 12:27:52PM +0300, Tomi Valkeinen wrote:
> > On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:
> > 
> > > Or you could use the driver_data field on the platform_device_id and
> > > of_device_id structures for that. Something like:
> > > 
> > > static const struct platform_device_id dss_id_table[] __initconst = {
> > > {
> > > 	{ "omap2-dss", omap2_dss_features },
> > > 	{ "omap3-dss", omap3_dss_features },
> > > 	{ "omap4-dss", omap4_dss_features },
> > > 	{ "omap5-dss", omap5_dss_features },
> > > 	{} /* Terminating entry */
> > > };
> > > 
> > > then, on your probe, you just need to copy id->driver_data to your own
> > > structures so you can reference them later. No need for cpu_is_* or
> > > soc_is_* or machine_is_* anywhere.
> > > 
> > > On your platform_code, wherever you create the dss device, you need to
> > > fix up the name though. The platform_device name should match
> > > platform_device_id name, not platform_driver name.
> > 
> > I've thought about that, but we need versions even for different OMAP ES
> > versions.
> > 
> > So in the device tree data we couldn't have the DSS nodes in a, say,
> > common omap4 file. We'd need separate DT files for each OMAP ES version.
> 
> you can overwrite attributes on your board dts file, right ? Meaning
> that e.g. omap4.dtsi would have:
> 
> dss1: dss@xxxx {
> 	compatible = "ti, omap4-dss";
> };
> 
> 
> then on omap4-based-board.dts:
> 
> &dss1 {
> 	compatible = "ti,omap4-based-board-dss";
> };
> 
> or something similar. Isn't that doable ? Benoit, would this work on
> DTS ?
> 

Yes, they can be overridden, but I think it's still quite difficult to
manage. DSS is modeled with multiple blocks, also in DT data. So you'd
need to override multiple entries.

And it'd also require a new dts file for each version of your board with
different ES version.

Also, I don't really see why this information would need to be present
in the DT data (especially as it's not simple). It's all trivially found
out in the code, by using cpu_is & soc_is.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07  9:57               ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07  9:57 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 2182 bytes --]

On Tue, 2012-08-07 at 12:32 +0300, Felipe Balbi wrote:
> Hi,
> 
> On Tue, Aug 07, 2012 at 12:27:52PM +0300, Tomi Valkeinen wrote:
> > On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:
> > 
> > > Or you could use the driver_data field on the platform_device_id and
> > > of_device_id structures for that. Something like:
> > > 
> > > static const struct platform_device_id dss_id_table[] __initconst = {
> > > {
> > > 	{ "omap2-dss", omap2_dss_features },
> > > 	{ "omap3-dss", omap3_dss_features },
> > > 	{ "omap4-dss", omap4_dss_features },
> > > 	{ "omap5-dss", omap5_dss_features },
> > > 	{} /* Terminating entry */
> > > };
> > > 
> > > then, on your probe, you just need to copy id->driver_data to your own
> > > structures so you can reference them later. No need for cpu_is_* or
> > > soc_is_* or machine_is_* anywhere.
> > > 
> > > On your platform_code, wherever you create the dss device, you need to
> > > fix up the name though. The platform_device name should match
> > > platform_device_id name, not platform_driver name.
> > 
> > I've thought about that, but we need versions even for different OMAP ES
> > versions.
> > 
> > So in the device tree data we couldn't have the DSS nodes in a, say,
> > common omap4 file. We'd need separate DT files for each OMAP ES version.
> 
> you can overwrite attributes on your board dts file, right ? Meaning
> that e.g. omap4.dtsi would have:
> 
> dss1: dss@xxxx {
> 	compatible = "ti, omap4-dss";
> };
> 
> 
> then on omap4-based-board.dts:
> 
> &dss1 {
> 	compatible = "ti,omap4-based-board-dss";
> };
> 
> or something similar. Isn't that doable ? Benoit, would this work on
> DTS ?
> 

Yes, they can be overridden, but I think it's still quite difficult to
manage. DSS is modeled with multiple blocks, also in DT data. So you'd
need to override multiple entries.

And it'd also require a new dts file for each version of your board with
different ES version.

Also, I don't really see why this information would need to be present
in the DT data (especially as it's not simple). It's all trivially found
out in the code, by using cpu_is & soc_is.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  9:57               ` Tomi Valkeinen
@ 2012-08-07 10:27                 ` Felipe Balbi
  -1 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07 10:27 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 2464 bytes --]

Hi,

On Tue, Aug 07, 2012 at 12:57:16PM +0300, Tomi Valkeinen wrote:
> On Tue, 2012-08-07 at 12:32 +0300, Felipe Balbi wrote:
> > Hi,
> > 
> > On Tue, Aug 07, 2012 at 12:27:52PM +0300, Tomi Valkeinen wrote:
> > > On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:
> > > 
> > > > Or you could use the driver_data field on the platform_device_id and
> > > > of_device_id structures for that. Something like:
> > > > 
> > > > static const struct platform_device_id dss_id_table[] __initconst = {
> > > > {
> > > > 	{ "omap2-dss", omap2_dss_features },
> > > > 	{ "omap3-dss", omap3_dss_features },
> > > > 	{ "omap4-dss", omap4_dss_features },
> > > > 	{ "omap5-dss", omap5_dss_features },
> > > > 	{} /* Terminating entry */
> > > > };
> > > > 
> > > > then, on your probe, you just need to copy id->driver_data to your own
> > > > structures so you can reference them later. No need for cpu_is_* or
> > > > soc_is_* or machine_is_* anywhere.
> > > > 
> > > > On your platform_code, wherever you create the dss device, you need to
> > > > fix up the name though. The platform_device name should match
> > > > platform_device_id name, not platform_driver name.
> > > 
> > > I've thought about that, but we need versions even for different OMAP ES
> > > versions.
> > > 
> > > So in the device tree data we couldn't have the DSS nodes in a, say,
> > > common omap4 file. We'd need separate DT files for each OMAP ES version.
> > 
> > you can overwrite attributes on your board dts file, right ? Meaning
> > that e.g. omap4.dtsi would have:
> > 
> > dss1: dss@xxxx {
> > 	compatible = "ti, omap4-dss";
> > };
> > 
> > 
> > then on omap4-based-board.dts:
> > 
> > &dss1 {
> > 	compatible = "ti,omap4-based-board-dss";
> > };
> > 
> > or something similar. Isn't that doable ? Benoit, would this work on
> > DTS ?
> > 
> 
> Yes, they can be overridden, but I think it's still quite difficult to
> manage. DSS is modeled with multiple blocks, also in DT data. So you'd
> need to override multiple entries.
> 
> And it'd also require a new dts file for each version of your board with
> different ES version.
> 
> Also, I don't really see why this information would need to be present
> in the DT data (especially as it's not simple). It's all trivially found
> out in the code, by using cpu_is & soc_is.

Fair enough. I just think we should remove all cpu_is_* and soc_is_*
from drivers.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07 10:27                 ` Felipe Balbi
  0 siblings, 0 replies; 146+ messages in thread
From: Felipe Balbi @ 2012-08-07 10:27 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 2464 bytes --]

Hi,

On Tue, Aug 07, 2012 at 12:57:16PM +0300, Tomi Valkeinen wrote:
> On Tue, 2012-08-07 at 12:32 +0300, Felipe Balbi wrote:
> > Hi,
> > 
> > On Tue, Aug 07, 2012 at 12:27:52PM +0300, Tomi Valkeinen wrote:
> > > On Tue, 2012-08-07 at 12:14 +0300, Felipe Balbi wrote:
> > > 
> > > > Or you could use the driver_data field on the platform_device_id and
> > > > of_device_id structures for that. Something like:
> > > > 
> > > > static const struct platform_device_id dss_id_table[] __initconst = {
> > > > {
> > > > 	{ "omap2-dss", omap2_dss_features },
> > > > 	{ "omap3-dss", omap3_dss_features },
> > > > 	{ "omap4-dss", omap4_dss_features },
> > > > 	{ "omap5-dss", omap5_dss_features },
> > > > 	{} /* Terminating entry */
> > > > };
> > > > 
> > > > then, on your probe, you just need to copy id->driver_data to your own
> > > > structures so you can reference them later. No need for cpu_is_* or
> > > > soc_is_* or machine_is_* anywhere.
> > > > 
> > > > On your platform_code, wherever you create the dss device, you need to
> > > > fix up the name though. The platform_device name should match
> > > > platform_device_id name, not platform_driver name.
> > > 
> > > I've thought about that, but we need versions even for different OMAP ES
> > > versions.
> > > 
> > > So in the device tree data we couldn't have the DSS nodes in a, say,
> > > common omap4 file. We'd need separate DT files for each OMAP ES version.
> > 
> > you can overwrite attributes on your board dts file, right ? Meaning
> > that e.g. omap4.dtsi would have:
> > 
> > dss1: dss@xxxx {
> > 	compatible = "ti, omap4-dss";
> > };
> > 
> > 
> > then on omap4-based-board.dts:
> > 
> > &dss1 {
> > 	compatible = "ti,omap4-based-board-dss";
> > };
> > 
> > or something similar. Isn't that doable ? Benoit, would this work on
> > DTS ?
> > 
> 
> Yes, they can be overridden, but I think it's still quite difficult to
> manage. DSS is modeled with multiple blocks, also in DT data. So you'd
> need to override multiple entries.
> 
> And it'd also require a new dts file for each version of your board with
> different ES version.
> 
> Also, I don't really see why this information would need to be present
> in the DT data (especially as it's not simple). It's all trivially found
> out in the code, by using cpu_is & soc_is.

Fair enough. I just think we should remove all cpu_is_* and soc_is_*
from drivers.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07  8:39   ` Chandrabhanu Mahapatra
@ 2012-08-07 10:52     ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 10:52 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra, Archit Taneja; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1367 bytes --]

Hi,

On Tue, 2012-08-07 at 13:57 +0530, Chandrabhanu Mahapatra wrote:
> The cpu_is checks have been removed from DISPC providing it a much generic and
> cleaner interface. The OMAP version and revision specific functions are
> initialized by dispc_ops structure in dss features.

I think this needs some changes. I think our general approach to these
version differences should be such that the component in question (dispc
in this case) should ask from somewhere what the DSS version is, and
then using that version, handle the different versions internally.

What that means related to this patch is that we should keep all those
functions static, and initialize the dispc_ops structure inside dispc.c.

However, we don't have any such "DSS version" yet. I have previously
wanted to move the cpu_is checks to one place (dss_features), but I
think it's probably cleaner if we allow cpu_is checks in the other files
also. However, there should be only one place in the file where those
should be.

So I think we should have something like this, called from
omap_dispchw_probe():

static void dispc_init_features(void)
{
	if (cpu_is_foo())
		setup features for this omap;
	else if (...)
		...
}

This would setup the ops, or whatever is needed. This function would be
the only place in dispc.c that contains cpu_is checks.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07 10:52     ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 10:52 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra, Archit Taneja; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1367 bytes --]

Hi,

On Tue, 2012-08-07 at 13:57 +0530, Chandrabhanu Mahapatra wrote:
> The cpu_is checks have been removed from DISPC providing it a much generic and
> cleaner interface. The OMAP version and revision specific functions are
> initialized by dispc_ops structure in dss features.

I think this needs some changes. I think our general approach to these
version differences should be such that the component in question (dispc
in this case) should ask from somewhere what the DSS version is, and
then using that version, handle the different versions internally.

What that means related to this patch is that we should keep all those
functions static, and initialize the dispc_ops structure inside dispc.c.

However, we don't have any such "DSS version" yet. I have previously
wanted to move the cpu_is checks to one place (dss_features), but I
think it's probably cleaner if we allow cpu_is checks in the other files
also. However, there should be only one place in the file where those
should be.

So I think we should have something like this, called from
omap_dispchw_probe():

static void dispc_init_features(void)
{
	if (cpu_is_foo())
		setup features for this omap;
	else if (...)
		...
}

This would setup the ops, or whatever is needed. This function would be
the only place in dispc.c that contains cpu_is checks.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07 10:27                 ` Felipe Balbi
@ 2012-08-07 10:57                   ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 10:57 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 954 bytes --]

On Tue, 2012-08-07 at 13:27 +0300, Felipe Balbi wrote:
> Hi,

> > Yes, they can be overridden, but I think it's still quite difficult to
> > manage. DSS is modeled with multiple blocks, also in DT data. So you'd
> > need to override multiple entries.
> > 
> > And it'd also require a new dts file for each version of your board with
> > different ES version.
> > 
> > Also, I don't really see why this information would need to be present
> > in the DT data (especially as it's not simple). It's all trivially found
> > out in the code, by using cpu_is & soc_is.
> 
> Fair enough. I just think we should remove all cpu_is_* and soc_is_*
> from drivers.

I agree, that's part of the idea here. Instead of having cpu_is checks
all around, we'll have them in only certain centralized places. Then
it's easier to implement a way to move them totally out of the driver,
when we come up with a good idea how to accomplish that.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07 10:57                   ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 10:57 UTC (permalink / raw)
  To: balbi; +Cc: Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

[-- Attachment #1: Type: text/plain, Size: 954 bytes --]

On Tue, 2012-08-07 at 13:27 +0300, Felipe Balbi wrote:
> Hi,

> > Yes, they can be overridden, but I think it's still quite difficult to
> > manage. DSS is modeled with multiple blocks, also in DT data. So you'd
> > need to override multiple entries.
> > 
> > And it'd also require a new dts file for each version of your board with
> > different ES version.
> > 
> > Also, I don't really see why this information would need to be present
> > in the DT data (especially as it's not simple). It's all trivially found
> > out in the code, by using cpu_is & soc_is.
> 
> Fair enough. I just think we should remove all cpu_is_* and soc_is_*
> from drivers.

I agree, that's part of the idea here. Instead of having cpu_is checks
all around, we'll have them in only certain centralized places. Then
it's easier to implement a way to move them totally out of the driver,
when we come up with a good idea how to accomplish that.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07 10:57                   ` Tomi Valkeinen
@ 2012-08-07 11:14                     ` Tony Lindgren
  -1 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-08-07 11:14 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120807 03:57]:
> On Tue, 2012-08-07 at 13:27 +0300, Felipe Balbi wrote:
> > Hi,
> 
> > > Yes, they can be overridden, but I think it's still quite difficult to
> > > manage. DSS is modeled with multiple blocks, also in DT data. So you'd
> > > need to override multiple entries.
> > > 
> > > And it'd also require a new dts file for each version of your board with
> > > different ES version.
> > > 
> > > Also, I don't really see why this information would need to be present
> > > in the DT data (especially as it's not simple). It's all trivially found
> > > out in the code, by using cpu_is & soc_is.
> > 
> > Fair enough. I just think we should remove all cpu_is_* and soc_is_*
> > from drivers.
> 
> I agree, that's part of the idea here. Instead of having cpu_is checks
> all around, we'll have them in only certain centralized places. Then
> it's easier to implement a way to move them totally out of the driver,
> when we come up with a good idea how to accomplish that.

Yes limiting them to driver init and setting some driver specific flags
based on that is a good start. But eventually no drivers should have
those checks.

Regards,

Tony

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07 11:14                     ` Tony Lindgren
  0 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-08-07 11:14 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: balbi, Chandrabhanu Mahapatra, linux-omap, linux-fbdev, Benoit Cousson

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120807 03:57]:
> On Tue, 2012-08-07 at 13:27 +0300, Felipe Balbi wrote:
> > Hi,
> 
> > > Yes, they can be overridden, but I think it's still quite difficult to
> > > manage. DSS is modeled with multiple blocks, also in DT data. So you'd
> > > need to override multiple entries.
> > > 
> > > And it'd also require a new dts file for each version of your board with
> > > different ES version.
> > > 
> > > Also, I don't really see why this information would need to be present
> > > in the DT data (especially as it's not simple). It's all trivially found
> > > out in the code, by using cpu_is & soc_is.
> > 
> > Fair enough. I just think we should remove all cpu_is_* and soc_is_*
> > from drivers.
> 
> I agree, that's part of the idea here. Instead of having cpu_is checks
> all around, we'll have them in only certain centralized places. Then
> it's easier to implement a way to move them totally out of the driver,
> when we come up with a good idea how to accomplish that.

Yes limiting them to driver init and setting some driver specific flags
based on that is a good start. But eventually no drivers should have
those checks.

Regards,

Tony

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07 10:52     ` Tomi Valkeinen
@ 2012-08-07 12:34       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07 12:22 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, linux-omap, linux-fbdev

On Tuesday 07 August 2012 04:22 PM, Tomi Valkeinen wrote:
> Hi,
>
> On Tue, 2012-08-07 at 13:57 +0530, Chandrabhanu Mahapatra wrote:
>> The cpu_is checks have been removed from DISPC providing it a much generic and
>> cleaner interface. The OMAP version and revision specific functions are
>> initialized by dispc_ops structure in dss features.
> I think this needs some changes. I think our general approach to these
> version differences should be such that the component in question (dispc
> in this case) should ask from somewhere what the DSS version is, and
> then using that version, handle the different versions internally.
>
> What that means related to this patch is that we should keep all those
> functions static, and initialize the dispc_ops structure inside dispc.c.
>
> However, we don't have any such "DSS version" yet. I have previously
> wanted to move the cpu_is checks to one place (dss_features), but I
> think it's probably cleaner if we allow cpu_is checks in the other files
> also. However, there should be only one place in the file where those
> should be.
>
> So I think we should have something like this, called from
> omap_dispchw_probe():
>
> static void dispc_init_features(void)
> {
> 	if (cpu_is_foo())
> 		setup features for this omap;
> 	else if (...)
> 		...
> }
>
> This would setup the ops, or whatever is needed. This function would be
> the only place in dispc.c that contains cpu_is checks.
>
>  Tomi
>
Yes, this seems good to me. Its better to have all cpu_is checks of
dispc.c and dss.c in their probe functions and by the time
implementation of DSS version come to picture these can be move to dss
features or any other place appropriate. But how to handle OMAP revision
specific functions. Will Dss version handle that too, as like DSS1,
DSS1.1, DSS1.1.1, DSS2 say?

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07 12:34       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07 12:34 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, linux-omap, linux-fbdev

On Tuesday 07 August 2012 04:22 PM, Tomi Valkeinen wrote:
> Hi,
>
> On Tue, 2012-08-07 at 13:57 +0530, Chandrabhanu Mahapatra wrote:
>> The cpu_is checks have been removed from DISPC providing it a much generic and
>> cleaner interface. The OMAP version and revision specific functions are
>> initialized by dispc_ops structure in dss features.
> I think this needs some changes. I think our general approach to these
> version differences should be such that the component in question (dispc
> in this case) should ask from somewhere what the DSS version is, and
> then using that version, handle the different versions internally.
>
> What that means related to this patch is that we should keep all those
> functions static, and initialize the dispc_ops structure inside dispc.c.
>
> However, we don't have any such "DSS version" yet. I have previously
> wanted to move the cpu_is checks to one place (dss_features), but I
> think it's probably cleaner if we allow cpu_is checks in the other files
> also. However, there should be only one place in the file where those
> should be.
>
> So I think we should have something like this, called from
> omap_dispchw_probe():
>
> static void dispc_init_features(void)
> {
> 	if (cpu_is_foo())
> 		setup features for this omap;
> 	else if (...)
> 		...
> }
>
> This would setup the ops, or whatever is needed. This function would be
> the only place in dispc.c that contains cpu_is checks.
>
>  Tomi
>
Yes, this seems good to me. Its better to have all cpu_is checks of
dispc.c and dss.c in their probe functions and by the time
implementation of DSS version come to picture these can be move to dss
features or any other place appropriate. But how to handle OMAP revision
specific functions. Will Dss version handle that too, as like DSS1,
DSS1.1, DSS1.1.1, DSS2 say?

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
  2012-08-07  8:51     ` Felipe Balbi
@ 2012-08-07 12:48       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07 12:36 UTC (permalink / raw)
  To: balbi; +Cc: linux-omap, linux-fbdev

On Tuesday 07 August 2012 02:21 PM, Felipe Balbi wrote:
> On Tue, Aug 07, 2012 at 01:58:17PM +0530, Chandrabhanu Mahapatra wrote:
>> OMAP4 checks are removed from VENC to provide it a cleaner interface. These
>> checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
>> to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
>> "OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
>> OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
>> from crashing OMAP4 kernel. An alternative approach is used to do the same in
>> later patches.
> in later patches ? This means you're causing a regression here. Just
> swap the patches around to avoid it.
>
Hi! Yes I do agree with you. But as VENC is disabled on omap4, the basic
idea here was to remove unnecessary cpu_is checks and achieve the same
through a better approach.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
@ 2012-08-07 12:48       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-07 12:48 UTC (permalink / raw)
  To: balbi; +Cc: linux-omap, linux-fbdev

On Tuesday 07 August 2012 02:21 PM, Felipe Balbi wrote:
> On Tue, Aug 07, 2012 at 01:58:17PM +0530, Chandrabhanu Mahapatra wrote:
>> OMAP4 checks are removed from VENC to provide it a cleaner interface. These
>> checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
>> to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
>> "OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
>> OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
>> from crashing OMAP4 kernel. An alternative approach is used to do the same in
>> later patches.
> in later patches ? This means you're causing a regression here. Just
> swap the patches around to avoid it.
>
Hi! Yes I do agree with you. But as VENC is disabled on omap4, the basic
idea here was to remove unnecessary cpu_is checks and achieve the same
through a better approach.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
  2012-08-07 12:34       ` Chandrabhanu Mahapatra
@ 2012-08-07 13:00         ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 13:00 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: Archit Taneja, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1409 bytes --]

On Tue, 2012-08-07 at 17:52 +0530, Chandrabhanu Mahapatra wrote:

> Yes, this seems good to me. Its better to have all cpu_is checks of
> dispc.c and dss.c in their probe functions and by the time
> implementation of DSS version come to picture these can be move to dss
> features or any other place appropriate. But how to handle OMAP revision
> specific functions. Will Dss version handle that too, as like DSS1,
> DSS1.1, DSS1.1.1, DSS2 say?

Yes, something like that.

I'm not sure how the version numbers should be created, though. If we
had only OMAP, we could use the OMAP version as the DSS major version,
and increasing minor version whenever the DSS is changed. So DSS3.2
could be the DSS used on OMAP3 SoCs, and it's the second revision,
meaning that early OMAP3 versions would have had an different DSS
version.

However, the same DSS is used for other SoCs also, so the versioning is
not that simple. I guess the other SoCs still always use a DSS that is
designed for OMAP, so the major version would be solved by that. For
example, AM3xxx DSS version would be DSS3.x. Minor version is more
tricky, because OMAP and AM3 DSS can evolve separately, which means that
a higher minor version may not contain the fix that exists in a lower
minor version.

Well, at least currently the AM3xxx's DSS is almost the same as OMAP3's,
so perhaps I'm worrying too much.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks
@ 2012-08-07 13:00         ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 13:00 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: Archit Taneja, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1409 bytes --]

On Tue, 2012-08-07 at 17:52 +0530, Chandrabhanu Mahapatra wrote:

> Yes, this seems good to me. Its better to have all cpu_is checks of
> dispc.c and dss.c in their probe functions and by the time
> implementation of DSS version come to picture these can be move to dss
> features or any other place appropriate. But how to handle OMAP revision
> specific functions. Will Dss version handle that too, as like DSS1,
> DSS1.1, DSS1.1.1, DSS2 say?

Yes, something like that.

I'm not sure how the version numbers should be created, though. If we
had only OMAP, we could use the OMAP version as the DSS major version,
and increasing minor version whenever the DSS is changed. So DSS3.2
could be the DSS used on OMAP3 SoCs, and it's the second revision,
meaning that early OMAP3 versions would have had an different DSS
version.

However, the same DSS is used for other SoCs also, so the versioning is
not that simple. I guess the other SoCs still always use a DSS that is
designed for OMAP, so the major version would be solved by that. For
example, AM3xxx DSS version would be DSS3.x. Minor version is more
tricky, because OMAP and AM3 DSS can evolve separately, which means that
a higher minor version may not contain the fix that exists in a lower
minor version.

Well, at least currently the AM3xxx's DSS is almost the same as OMAP3's,
so perhaps I'm worrying too much.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Remove cpu_is_xxxx checks
  2012-08-07  8:40   ` Chandrabhanu Mahapatra
@ 2012-08-07 13:14     ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 13:14 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2515 bytes --]

On Tue, 2012-08-07 at 13:58 +0530, Chandrabhanu Mahapatra wrote:
> The cpu_is checks have been removed from dss.c providing it a much generic and
> cleaner interface. The OMAP version and revision specific functions are
> initialized by dss_ops structure in dss features.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c          |  114 ++++++++++++++++++++++----------
>  drivers/video/omap2/dss/dss.h          |   23 ++++++-
>  drivers/video/omap2/dss/dss_features.c |   40 +++++++++++
>  drivers/video/omap2/dss/dss_features.h |    1 +
>  4 files changed, 141 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..c263da7 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -83,6 +83,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_ops *ops;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -236,6 +238,15 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> +char *set_dump_clk_str_24_34(void)
> +{
> +	return "%s (%s) = %lu / %lu * 2  = %lu\n";
> +}
> +
> +char *set_dump_clk_str(void)
> +{
> +	return "%s (%s) = %lu / %lu  = %lu\n";
> +}

You don't need functions for these, or for the max fck div. Just add the
string or the number to the struct.

And I don't really like the format string being separately. It would
probably be better if you instead had just a flag for the x2 multiplier,
and the dump function would check the flag to see which format string it
uses.

> @@ -479,10 +511,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
> -	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && dss.ops->set_dss_cinfo()) {
>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;

This is quite confusing. "set" function should set something, normally
something that is given as a parameter. Your function seems to be
checking some values.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Remove cpu_is_xxxx checks
@ 2012-08-07 13:14     ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 13:14 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2515 bytes --]

On Tue, 2012-08-07 at 13:58 +0530, Chandrabhanu Mahapatra wrote:
> The cpu_is checks have been removed from dss.c providing it a much generic and
> cleaner interface. The OMAP version and revision specific functions are
> initialized by dss_ops structure in dss features.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c          |  114 ++++++++++++++++++++++----------
>  drivers/video/omap2/dss/dss.h          |   23 ++++++-
>  drivers/video/omap2/dss/dss_features.c |   40 +++++++++++
>  drivers/video/omap2/dss/dss_features.h |    1 +
>  4 files changed, 141 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..c263da7 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -83,6 +83,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_ops *ops;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -236,6 +238,15 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> +char *set_dump_clk_str_24_34(void)
> +{
> +	return "%s (%s) = %lu / %lu * 2  = %lu\n";
> +}
> +
> +char *set_dump_clk_str(void)
> +{
> +	return "%s (%s) = %lu / %lu  = %lu\n";
> +}

You don't need functions for these, or for the max fck div. Just add the
string or the number to the struct.

And I don't really like the format string being separately. It would
probably be better if you instead had just a flag for the x2 multiplier,
and the dump function would check the flag to see which format string it
uses.

> @@ -479,10 +511,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
> -	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && dss.ops->set_dss_cinfo()) {
>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;

This is quite confusing. "set" function should set something, normally
something that is given as a parameter. Your function seems to be
checking some values.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-07  8:39   ` Chandrabhanu Mahapatra
@ 2012-08-08 11:49     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-08 11:37 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions are initialized by dispc_features structure local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  476 ++++++++++++++++++++++++++-------------
 1 file changed, 315 insertions(+), 161 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..7e0b080 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -75,12 +75,60 @@ enum omap_burst_size {
 #define REG_FLD_MOD(idx, val, start, end)				\
 	dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
 
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+
+static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+
+static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
+static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
+
 struct dispc_irq_stats {
 	unsigned long last_reset;
 	unsigned irq_count;
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+	bool (*lcd_timings_ok) (int hsw, int hfp, int hbp,
+			int vsw, int vfp, int vbp);
+	void (*set_lcd_timings_hv) (enum omap_channel channel, int hsw, int hfp,
+			int hbp, int vsw, int vfp, int vbp);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +149,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -210,6 +260,34 @@ static const struct {
 	},
 };
 
+static const struct dispc_features omap2_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_features omap3_2_1_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_features omap3_3_0_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
+static const struct dispc_features omap4_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
 static void _omap_dispc_set_irqs(void);
 
 static inline void dispc_write_reg(const u16 idx, u32 val)
@@ -1939,7 +2017,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +2047,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth =
+				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
 	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2215,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth =
-				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width == out_width && height == out_height)
 		return 0;
@@ -2017,118 +2241,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2601,27 +2724,28 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 		height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT);
 }
 
-static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
+static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > 64 ||
+			hfp < 1 || hfp > 256 ||
+			hbp < 1 || hbp > 256 ||
+			vsw < 1 || vsw > 64  ||
+			vfp < 0 || vfp > 255 ||
+			vbp < 0 || vbp > 255)
+		return false;
+	return true;
+}
+static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp)
+{
+	if (hsw < 1 || hsw > 256 ||
+			hfp < 1  || hfp > 4096 ||
+			hbp < 1  || hbp > 4096 ||
+			vsw < 1  || vsw > 256  ||
+			vfp < 0  || vfp > 4095 ||
+			vbp < 0  || vbp > 4095)
+		return false;
 	return true;
 }
 
@@ -2633,7 +2757,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
 
 	if (dss_mgr_is_lcd(channel))
-		timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
+		timings_ok =  timings_ok &&
+			dispc.feat->lcd_timings_ok(timings->hsw,
 						timings->hfp, timings->hbp,
 						timings->vsw, timings->vfp,
 						timings->vbp);
@@ -2641,6 +2766,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	return timings_ok;
 }
 
+static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
+			FLD_VAL(hbp-1, 27, 20);
+	timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
+			FLD_VAL(vbp, 27, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
+static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
+			FLD_VAL(hbp-1, 31, 20);
+	timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
+			FLD_VAL(vbp, 31, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
 static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		int hfp, int hbp, int vsw, int vfp, int vbp,
 		enum omap_dss_signal_level vsync_level,
@@ -2650,25 +2803,10 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		enum omap_dss_signal_edge sync_pclk_edge)
 
 {
-	u32 timing_h, timing_v, l;
+	u32 l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
-
-	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
-	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+	dispc.feat->set_lcd_timings_hv(channel, hsw, hfp, hbp, vsw, vfp, vbp);
 
 	switch (data_pclk_edge) {
 	case OMAPDSS_DRIVE_SIG_RISING_EDGE:
@@ -3671,6 +3809,20 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static void dispc_init_features(void)
+{
+	if (cpu_is_omap24xx()) {
+		dispc.feat = &omap2_dispc_features;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			dispc.feat = &omap3_2_1_dispc_features;
+		else
+			dispc.feat = &omap3_3_0_dispc_features;
+	} else {
+		dispc.feat = &omap4_dispc_features;
+	}
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3725,6 +3877,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	dispc_init_features();
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-07  8:40   ` Chandrabhanu Mahapatra
@ 2012-08-08 11:50     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-08 11:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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
functions are initialized by dss_features structure local to dss.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |  154 ++++++++++++++++++++++++++++++-----------
 1 file changed, 114 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..f5971ac 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -65,6 +65,20 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+static bool check_dss_cinfo_fck(void);
+static bool check_dss_cinfo_fck_34xx(void);
+
+static int dss_get_clk_24xx(struct clk *clk);
+static int dss_get_clk_3xxx(struct clk *clk);
+static int dss_get_clk_44xx(struct clk *clk);
+
+struct dss_features {
+	u16 fck_div_max;
+	int factor;
+	bool (*check_cinfo_fck) (void);
+	int (*get_clk) (struct clk *clk);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +97,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +107,34 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap2_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.check_cinfo_fck	=	check_dss_cinfo_fck,
+	.get_clk		=	dss_get_clk_24xx,
+};
+
+static const struct dss_features omap34_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.check_cinfo_fck	=	check_dss_cinfo_fck_34xx,
+	.get_clk		=	dss_get_clk_3xxx,
+};
+
+static const struct dss_features omap36_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.check_cinfo_fck	=	check_dss_cinfo_fck,
+	.get_clk		=	dss_get_clk_3xxx,
+};
+
+static const struct dss_features omap4_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.check_cinfo_fck	=	check_dss_cinfo_fck,
+	.get_clk		=	dss_get_clk_44xx,
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__raw_writel(val, dss.base + idx.idx);
@@ -236,7 +280,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +302,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->factor, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -461,6 +496,25 @@ unsigned long dss_get_dpll4_rate(void)
 		return 0;
 }
 
+static bool check_dss_cinfo_fck_34xx(void)
+{
+	unsigned long prate = dss_get_dpll4_rate();
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (prate == dss.cache_prate || dss.cache_dss_cinfo.fck == fck)
+		return true;
+	return false;
+}
+
+static bool check_dss_cinfo_fck(void)
+{
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (dss.cache_dss_cinfo.fck == fck)
+		return true;
+	return false;
+}
+
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo)
 {
@@ -470,7 +524,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -479,10 +533,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
-	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck == dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck == fck)) {
+	if (req_pck == dss.cache_req_pck && dss.feat->check_cinfo_fck()) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,13 +570,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max == 32)
+			if (dss.feat->fck_div_max == 32)
 				fck = prate / fck_div;
 			else
 				fck = prate / fck_div * 2;
@@ -619,6 +667,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
 	return REG_GET(DSS_CONTROL, 15, 15);
 }
 
+static int dss_get_clk_24xx(struct clk *clk)
+{
+	clk = NULL;
+	return true;
+}
+
+static int dss_get_clk_3xxx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll4_m4_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll4_m4_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
+static int dss_get_clk_44xx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll_per_m5x2_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll_per_m5x2_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
 static int dss_get_clocks(void)
 {
 	struct clk *clk;
@@ -633,23 +707,9 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
-	}
+	r = dss.feat->get_clk(clk);
+	if (r != true)
+		goto err;
 
 	dss.dpll4_m4_ck = clk;
 
@@ -704,6 +764,18 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static void dss_init_features(void)
+{
+	if (cpu_is_omap24xx())
+		dss.feat = &omap2_dss_features;
+	else if (cpu_is_omap34xx())
+		dss.feat = &omap34_dss_features;
+	else if (cpu_is_omap3630())
+		dss.feat = &omap36_dss_features;
+	else
+		dss.feat = &omap4_dss_features;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -750,6 +822,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	dss_init_features();
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-08 11:49     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-08 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions are initialized by dispc_features structure local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  476 ++++++++++++++++++++++++++-------------
 1 file changed, 315 insertions(+), 161 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..7e0b080 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -75,12 +75,60 @@ enum omap_burst_size {
 #define REG_FLD_MOD(idx, val, start, end)				\
 	dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
 
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
+	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
+	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
+	int *decim_y, u16 pos_x, unsigned long *core_clk);
+
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height);
+
+static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp);
+
+static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
+static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
+
 struct dispc_irq_stats {
 	unsigned long last_reset;
 	unsigned irq_count;
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+	bool (*lcd_timings_ok) (int hsw, int hfp, int hbp,
+			int vsw, int vfp, int vbp);
+	void (*set_lcd_timings_hv) (enum omap_channel channel, int hsw, int hfp,
+			int hbp, int vsw, int vfp, int vbp);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +149,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -210,6 +260,34 @@ static const struct {
 	},
 };
 
+static const struct dispc_features omap2_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_features omap3_2_1_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
+};
+
+static const struct dispc_features omap3_3_0_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
+static const struct dispc_features omap4_dispc_features = {
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
+	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
+};
+
 static void _omap_dispc_set_irqs(void);
 
 static inline void dispc_write_reg(const u16 idx, u32 val)
@@ -1939,7 +2017,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +2047,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth +				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
 	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2215,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth -				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width = out_width && height = out_height)
 		return 0;
@@ -2017,118 +2241,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2601,27 +2724,28 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 		height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT);
 }
 
-static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
+static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > 64 ||
+			hfp < 1 || hfp > 256 ||
+			hbp < 1 || hbp > 256 ||
+			vsw < 1 || vsw > 64  ||
+			vfp < 0 || vfp > 255 ||
+			vbp < 0 || vbp > 255)
+		return false;
+	return true;
+}
+static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp)
+{
+	if (hsw < 1 || hsw > 256 ||
+			hfp < 1  || hfp > 4096 ||
+			hbp < 1  || hbp > 4096 ||
+			vsw < 1  || vsw > 256  ||
+			vfp < 0  || vfp > 4095 ||
+			vbp < 0  || vbp > 4095)
+		return false;
 	return true;
 }
 
@@ -2633,7 +2757,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
 
 	if (dss_mgr_is_lcd(channel))
-		timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
+		timings_ok =  timings_ok &&
+			dispc.feat->lcd_timings_ok(timings->hsw,
 						timings->hfp, timings->hbp,
 						timings->vsw, timings->vfp,
 						timings->vbp);
@@ -2641,6 +2766,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 	return timings_ok;
 }
 
+static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
+			FLD_VAL(hbp-1, 27, 20);
+	timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
+			FLD_VAL(vbp, 27, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
+static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
+		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
+			FLD_VAL(hbp-1, 31, 20);
+	timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
+			FLD_VAL(vbp, 31, 20);
+
+	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
+	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+}
+
 static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		int hfp, int hbp, int vsw, int vfp, int vbp,
 		enum omap_dss_signal_level vsync_level,
@@ -2650,25 +2803,10 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 		enum omap_dss_signal_edge sync_pclk_edge)
 
 {
-	u32 timing_h, timing_v, l;
+	u32 l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
-
-	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
-	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
+	dispc.feat->set_lcd_timings_hv(channel, hsw, hfp, hbp, vsw, vfp, vbp);
 
 	switch (data_pclk_edge) {
 	case OMAPDSS_DRIVE_SIG_RISING_EDGE:
@@ -3671,6 +3809,20 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static void dispc_init_features(void)
+{
+	if (cpu_is_omap24xx()) {
+		dispc.feat = &omap2_dispc_features;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			dispc.feat = &omap3_2_1_dispc_features;
+		else
+			dispc.feat = &omap3_3_0_dispc_features;
+	} else {
+		dispc.feat = &omap4_dispc_features;
+	}
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3725,6 +3877,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	dispc_init_features();
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-08 11:50     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-08 11:50 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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
functions are initialized by dss_features structure local to dss.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |  154 ++++++++++++++++++++++++++++++-----------
 1 file changed, 114 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..f5971ac 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -65,6 +65,20 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+static bool check_dss_cinfo_fck(void);
+static bool check_dss_cinfo_fck_34xx(void);
+
+static int dss_get_clk_24xx(struct clk *clk);
+static int dss_get_clk_3xxx(struct clk *clk);
+static int dss_get_clk_44xx(struct clk *clk);
+
+struct dss_features {
+	u16 fck_div_max;
+	int factor;
+	bool (*check_cinfo_fck) (void);
+	int (*get_clk) (struct clk *clk);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +97,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +107,34 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap2_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.check_cinfo_fck	=	check_dss_cinfo_fck,
+	.get_clk		=	dss_get_clk_24xx,
+};
+
+static const struct dss_features omap34_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.check_cinfo_fck	=	check_dss_cinfo_fck_34xx,
+	.get_clk		=	dss_get_clk_3xxx,
+};
+
+static const struct dss_features omap36_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.check_cinfo_fck	=	check_dss_cinfo_fck,
+	.get_clk		=	dss_get_clk_3xxx,
+};
+
+static const struct dss_features omap4_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.check_cinfo_fck	=	check_dss_cinfo_fck,
+	.get_clk		=	dss_get_clk_44xx,
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__raw_writel(val, dss.base + idx.idx);
@@ -236,7 +280,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +302,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->factor, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -461,6 +496,25 @@ unsigned long dss_get_dpll4_rate(void)
 		return 0;
 }
 
+static bool check_dss_cinfo_fck_34xx(void)
+{
+	unsigned long prate = dss_get_dpll4_rate();
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (prate = dss.cache_prate || dss.cache_dss_cinfo.fck = fck)
+		return true;
+	return false;
+}
+
+static bool check_dss_cinfo_fck(void)
+{
+	unsigned long fck = clk_get_rate(dss.dss_clk);
+
+	if (dss.cache_dss_cinfo.fck = fck)
+		return true;
+	return false;
+}
+
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo)
 {
@@ -470,7 +524,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -479,10 +533,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
-	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck = dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate = dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck = fck)) {
+	if (req_pck = dss.cache_req_pck && dss.feat->check_cinfo_fck()) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,13 +570,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max = 32)
+			if (dss.feat->fck_div_max = 32)
 				fck = prate / fck_div;
 			else
 				fck = prate / fck_div * 2;
@@ -619,6 +667,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
 	return REG_GET(DSS_CONTROL, 15, 15);
 }
 
+static int dss_get_clk_24xx(struct clk *clk)
+{
+	clk = NULL;
+	return true;
+}
+
+static int dss_get_clk_3xxx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll4_m4_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll4_m4_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
+static int dss_get_clk_44xx(struct clk *clk)
+{
+	clk = clk_get(NULL, "dpll_per_m5x2_ck");
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get dpll_per_m5x2_ck\n");
+		return PTR_ERR(clk);
+	}
+	return true;
+}
+
 static int dss_get_clocks(void)
 {
 	struct clk *clk;
@@ -633,23 +707,9 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
-	}
+	r = dss.feat->get_clk(clk);
+	if (r != true)
+		goto err;
 
 	dss.dpll4_m4_ck = clk;
 
@@ -704,6 +764,18 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static void dss_init_features(void)
+{
+	if (cpu_is_omap24xx())
+		dss.feat = &omap2_dss_features;
+	else if (cpu_is_omap34xx())
+		dss.feat = &omap34_dss_features;
+	else if (cpu_is_omap3630())
+		dss.feat = &omap36_dss_features;
+	else
+		dss.feat = &omap4_dss_features;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -750,6 +822,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	dss_init_features();
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-08 11:49     ` Chandrabhanu Mahapatra
@ 2012-08-08 12:36       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-08 12:36 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 7991 bytes --]

On Wed, 2012-08-08 at 17:07 +0530, Chandrabhanu Mahapatra wrote:
> All the cpu_is checks have been moved to dispc_init_features function providing
> a much more generic and cleaner interface. The OMAP version and revision
> specific functions are initialized by dispc_features structure local to dispc.c.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dispc.c |  476 ++++++++++++++++++++++++++-------------
>  1 file changed, 315 insertions(+), 161 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index 5b289c5..7e0b080 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -75,12 +75,60 @@ enum omap_burst_size {
>  #define REG_FLD_MOD(idx, val, start, end)				\
>  	dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
>  
> +static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
> +	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
> +	u16 out_width, u16 out_height, enum omap_color_mode color_mode,
> +	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
> +	int *decim_y, u16 pos_x, unsigned long *core_clk);
> +static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
> +	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
> +	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
> +	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
> +	int *decim_y, u16 pos_x, unsigned long *core_clk);
> +static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
> +	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
> +	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
> +	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
> +	int *decim_y, u16 pos_x, unsigned long *core_clk);
> +
> +static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
> +		u16 height, u16 out_width, u16 out_height);
> +static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
> +		u16 height, u16 out_width, u16 out_height);
> +static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
> +		u16 height, u16 out_width, u16 out_height);
> +
> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
> +		int vsw, int vfp, int vbp);
> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
> +		int vsw, int vfp, int vbp);
> +
> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);

While it's nice to have the initialization of struct dispc_features in
the beginning of dispc.c, it requires the above prototypes. And in the
future we may require more. For that reason I think it's better to
initialize the dispc_features at the end of dispc.c, just above
dispc_init_features(). This would be kinda similar to how drivers often
initialize their ops. 

> +static const struct dispc_features omap2_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
> +	.calc_core_clk		=	calc_core_clk_24xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_features omap3_2_1_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_features omap3_3_0_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};
> +
> +static const struct dispc_features omap4_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
> +	.calc_core_clk		=	calc_core_clk_44xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};

During runtime we only require one of these, others can be discarded.
This can be accomplished with the combination of "__initdata" for these,
and "__init" for dispc_init_features().

However, because even the one we need will be discarded, we need to copy
the values. This could be done either by having the dispc_features
struct inside dispc struct (instead of a pointer), or allocating memory
for it with devm_kzalloc(). The latter allows us to keep it const, but
I'm not sure which approach is better (if either).

> -static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
>  		int vsw, int vfp, int vbp)
>  {
> -	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
> -		if (hsw < 1 || hsw > 64 ||
> -				hfp < 1 || hfp > 256 ||
> -				hbp < 1 || hbp > 256 ||
> -				vsw < 1 || vsw > 64 ||
> -				vfp < 0 || vfp > 255 ||
> -				vbp < 0 || vbp > 255)
> -			return false;
> -	} else {
> -		if (hsw < 1 || hsw > 256 ||
> -				hfp < 1 || hfp > 4096 ||
> -				hbp < 1 || hbp > 4096 ||
> -				vsw < 1 || vsw > 256 ||
> -				vfp < 0 || vfp > 4095 ||
> -				vbp < 0 || vbp > 4095)
> -			return false;
> -	}
> -
> +	if (hsw < 1 || hsw > 64 ||
> +			hfp < 1 || hfp > 256 ||
> +			hbp < 1 || hbp > 256 ||
> +			vsw < 1 || vsw > 64  ||
> +			vfp < 0 || vfp > 255 ||
> +			vbp < 0 || vbp > 255)
> +		return false;
> +	return true;
> +}
> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
> +		int vsw, int vfp, int vbp)
> +{
> +	if (hsw < 1 || hsw > 256 ||
> +			hfp < 1  || hfp > 4096 ||
> +			hbp < 1  || hbp > 4096 ||
> +			vsw < 1  || vsw > 256  ||
> +			vfp < 0  || vfp > 4095 ||
> +			vbp < 0  || vbp > 4095)
> +		return false;
>  	return true;
>  }

I think we should use separate functions only when the code is
different. Here the code is the same, we just use different max values.

So instead of these functions, I suggest to add those max values into
struct dispc_features.

> @@ -2633,7 +2757,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>  	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
>  
>  	if (dss_mgr_is_lcd(channel))
> -		timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
> +		timings_ok =  timings_ok &&
> +			dispc.feat->lcd_timings_ok(timings->hsw,
>  						timings->hfp, timings->hbp,
>  						timings->vsw, timings->vfp,
>  						timings->vbp);
> @@ -2641,6 +2766,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>  	return timings_ok;
>  }
>  
> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
> +{
> +	u32 timing_h, timing_v;
> +
> +	timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
> +			FLD_VAL(hbp-1, 27, 20);
> +	timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
> +			FLD_VAL(vbp, 27, 20);
> +
> +	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
> +	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
> +}
> +
> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
> +{
> +	u32 timing_h, timing_v;
> +
> +	timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
> +			FLD_VAL(hbp-1, 31, 20);
> +	timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
> +			FLD_VAL(vbp, 31, 20);
> +
> +	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
> +	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
> +}

Same thing here. The code is the same, only the bit fields are larger.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-08 12:36       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-08 12:36 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 7991 bytes --]

On Wed, 2012-08-08 at 17:07 +0530, Chandrabhanu Mahapatra wrote:
> All the cpu_is checks have been moved to dispc_init_features function providing
> a much more generic and cleaner interface. The OMAP version and revision
> specific functions are initialized by dispc_features structure local to dispc.c.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dispc.c |  476 ++++++++++++++++++++++++++-------------
>  1 file changed, 315 insertions(+), 161 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index 5b289c5..7e0b080 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -75,12 +75,60 @@ enum omap_burst_size {
>  #define REG_FLD_MOD(idx, val, start, end)				\
>  	dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
>  
> +static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
> +	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
> +	u16 out_width, u16 out_height, enum omap_color_mode color_mode,
> +	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
> +	int *decim_y, u16 pos_x, unsigned long *core_clk);
> +static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
> +	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
> +	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
> +	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
> +	int *decim_y, u16 pos_x, unsigned long *core_clk);
> +static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
> +	const struct omap_video_timings *mgr_timings, u16 width, u16 height,
> +	u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
> +	bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
> +	int *decim_y, u16 pos_x, unsigned long *core_clk);
> +
> +static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
> +		u16 height, u16 out_width, u16 out_height);
> +static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
> +		u16 height, u16 out_width, u16 out_height);
> +static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
> +		u16 height, u16 out_width, u16 out_height);
> +
> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
> +		int vsw, int vfp, int vbp);
> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
> +		int vsw, int vfp, int vbp);
> +
> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);

While it's nice to have the initialization of struct dispc_features in
the beginning of dispc.c, it requires the above prototypes. And in the
future we may require more. For that reason I think it's better to
initialize the dispc_features at the end of dispc.c, just above
dispc_init_features(). This would be kinda similar to how drivers often
initialize their ops. 

> +static const struct dispc_features omap2_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
> +	.calc_core_clk		=	calc_core_clk_24xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_features omap3_2_1_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_24xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_24xx,
> +};
> +
> +static const struct dispc_features omap3_3_0_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
> +	.calc_core_clk		=	calc_core_clk_34xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};
> +
> +static const struct dispc_features omap4_dispc_features = {
> +	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
> +	.calc_core_clk		=	calc_core_clk_44xx,
> +	.lcd_timings_ok		=	_dispc_lcd_timings_ok_44xx,
> +	.set_lcd_timings_hv	=	_dispc_mgr_set_lcd_timings_hv_44xx,
> +};

During runtime we only require one of these, others can be discarded.
This can be accomplished with the combination of "__initdata" for these,
and "__init" for dispc_init_features().

However, because even the one we need will be discarded, we need to copy
the values. This could be done either by having the dispc_features
struct inside dispc struct (instead of a pointer), or allocating memory
for it with devm_kzalloc(). The latter allows us to keep it const, but
I'm not sure which approach is better (if either).

> -static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
>  		int vsw, int vfp, int vbp)
>  {
> -	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
> -		if (hsw < 1 || hsw > 64 ||
> -				hfp < 1 || hfp > 256 ||
> -				hbp < 1 || hbp > 256 ||
> -				vsw < 1 || vsw > 64 ||
> -				vfp < 0 || vfp > 255 ||
> -				vbp < 0 || vbp > 255)
> -			return false;
> -	} else {
> -		if (hsw < 1 || hsw > 256 ||
> -				hfp < 1 || hfp > 4096 ||
> -				hbp < 1 || hbp > 4096 ||
> -				vsw < 1 || vsw > 256 ||
> -				vfp < 0 || vfp > 4095 ||
> -				vbp < 0 || vbp > 4095)
> -			return false;
> -	}
> -
> +	if (hsw < 1 || hsw > 64 ||
> +			hfp < 1 || hfp > 256 ||
> +			hbp < 1 || hbp > 256 ||
> +			vsw < 1 || vsw > 64  ||
> +			vfp < 0 || vfp > 255 ||
> +			vbp < 0 || vbp > 255)
> +		return false;
> +	return true;
> +}
> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
> +		int vsw, int vfp, int vbp)
> +{
> +	if (hsw < 1 || hsw > 256 ||
> +			hfp < 1  || hfp > 4096 ||
> +			hbp < 1  || hbp > 4096 ||
> +			vsw < 1  || vsw > 256  ||
> +			vfp < 0  || vfp > 4095 ||
> +			vbp < 0  || vbp > 4095)
> +		return false;
>  	return true;
>  }

I think we should use separate functions only when the code is
different. Here the code is the same, we just use different max values.

So instead of these functions, I suggest to add those max values into
struct dispc_features.

> @@ -2633,7 +2757,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>  	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
>  
>  	if (dss_mgr_is_lcd(channel))
> -		timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
> +		timings_ok =  timings_ok &&
> +			dispc.feat->lcd_timings_ok(timings->hsw,
>  						timings->hfp, timings->hbp,
>  						timings->vsw, timings->vfp,
>  						timings->vbp);
> @@ -2641,6 +2766,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>  	return timings_ok;
>  }
>  
> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
> +{
> +	u32 timing_h, timing_v;
> +
> +	timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
> +			FLD_VAL(hbp-1, 27, 20);
> +	timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
> +			FLD_VAL(vbp, 27, 20);
> +
> +	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
> +	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
> +}
> +
> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
> +		int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
> +{
> +	u32 timing_h, timing_v;
> +
> +	timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
> +			FLD_VAL(hbp-1, 31, 20);
> +	timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
> +			FLD_VAL(vbp, 31, 20);
> +
> +	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
> +	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
> +}

Same thing here. The code is the same, only the bit fields are larger.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-08 12:36       ` Tomi Valkeinen
@ 2012-08-08 13:13         ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-08 13:01 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Wed, Aug 8, 2012 at 6:06 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Wed, 2012-08-08 at 17:07 +0530, Chandrabhanu Mahapatra wrote:
>> All the cpu_is checks have been moved to dispc_init_features function providing
>> a much more generic and cleaner interface. The OMAP version and revision
>> specific functions are initialized by dispc_features structure local to dispc.c.
>>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dispc.c |  476 ++++++++++++++++++++++++++-------------
>>  1 file changed, 315 insertions(+), 161 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
>> index 5b289c5..7e0b080 100644
>> --- a/drivers/video/omap2/dss/dispc.c
>> +++ b/drivers/video/omap2/dss/dispc.c
>> @@ -75,12 +75,60 @@ enum omap_burst_size {
>>  #define REG_FLD_MOD(idx, val, start, end)                            \
>>       dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
>>
>> +static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
>> +     const struct omap_video_timings *mgr_timings, u16 width, u16 height,
>> +     u16 out_width, u16 out_height, enum omap_color_mode color_mode,
>> +     bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
>> +     int *decim_y, u16 pos_x, unsigned long *core_clk);
>> +static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
>> +     const struct omap_video_timings *mgr_timings, u16 width, u16 height,
>> +     u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
>> +     bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
>> +     int *decim_y, u16 pos_x, unsigned long *core_clk);
>> +static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
>> +     const struct omap_video_timings *mgr_timings, u16 width, u16 height,
>> +     u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
>> +     bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
>> +     int *decim_y, u16 pos_x, unsigned long *core_clk);
>> +
>> +static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
>> +             u16 height, u16 out_width, u16 out_height);
>> +static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
>> +             u16 height, u16 out_width, u16 out_height);
>> +static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
>> +             u16 height, u16 out_width, u16 out_height);
>> +
>> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
>> +             int vsw, int vfp, int vbp);
>> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
>> +             int vsw, int vfp, int vbp);
>> +
>> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
>> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
>
> While it's nice to have the initialization of struct dispc_features in
> the beginning of dispc.c, it requires the above prototypes. And in the
> future we may require more. For that reason I think it's better to
> initialize the dispc_features at the end of dispc.c, just above
> dispc_init_features(). This would be kinda similar to how drivers often
> initialize their ops.
>

Yes, this sounds good, but I was just following general order of
structure and function declarations, structures initializations
followed by functions.

>> +static const struct dispc_features omap2_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_24xx,
>> +     .calc_core_clk          =       calc_core_clk_24xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_24xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_24xx,
>> +};
>> +
>> +static const struct dispc_features omap3_2_1_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
>> +     .calc_core_clk          =       calc_core_clk_34xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_24xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_24xx,
>> +};
>> +
>> +static const struct dispc_features omap3_3_0_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
>> +     .calc_core_clk          =       calc_core_clk_34xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_44xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_44xx,
>> +};
>> +
>> +static const struct dispc_features omap4_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
>> +     .calc_core_clk          =       calc_core_clk_44xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_44xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_44xx,
>> +};
>
> During runtime we only require one of these, others can be discarded.
> This can be accomplished with the combination of "__initdata" for these,
> and "__init" for dispc_init_features().
>

The same also applies for all structures in dss_features.c. Just a
thought that __init and __initdata should have also been used there.

> However, because even the one we need will be discarded, we need to copy
> the values. This could be done either by having the dispc_features
> struct inside dispc struct (instead of a pointer), or allocating memory
> for it with devm_kzalloc(). The latter allows us to keep it const, but
> I'm not sure which approach is better (if either).
>

The latter approach seems better as we need to keep it const. I will
try out both anyways.

>> -static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
>> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
>>               int vsw, int vfp, int vbp)
>>  {
>> -     if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
>> -             if (hsw < 1 || hsw > 64 ||
>> -                             hfp < 1 || hfp > 256 ||
>> -                             hbp < 1 || hbp > 256 ||
>> -                             vsw < 1 || vsw > 64 ||
>> -                             vfp < 0 || vfp > 255 ||
>> -                             vbp < 0 || vbp > 255)
>> -                     return false;
>> -     } else {
>> -             if (hsw < 1 || hsw > 256 ||
>> -                             hfp < 1 || hfp > 4096 ||
>> -                             hbp < 1 || hbp > 4096 ||
>> -                             vsw < 1 || vsw > 256 ||
>> -                             vfp < 0 || vfp > 4095 ||
>> -                             vbp < 0 || vbp > 4095)
>> -                     return false;
>> -     }
>> -
>> +     if (hsw < 1 || hsw > 64 ||
>> +                     hfp < 1 || hfp > 256 ||
>> +                     hbp < 1 || hbp > 256 ||
>> +                     vsw < 1 || vsw > 64  ||
>> +                     vfp < 0 || vfp > 255 ||
>> +                     vbp < 0 || vbp > 255)
>> +             return false;
>> +     return true;
>> +}
>> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
>> +             int vsw, int vfp, int vbp)
>> +{
>> +     if (hsw < 1 || hsw > 256 ||
>> +                     hfp < 1  || hfp > 4096 ||
>> +                     hbp < 1  || hbp > 4096 ||
>> +                     vsw < 1  || vsw > 256  ||
>> +                     vfp < 0  || vfp > 4095 ||
>> +                     vbp < 0  || vbp > 4095)
>> +             return false;
>>       return true;
>>  }
>
> I think we should use separate functions only when the code is
> different. Here the code is the same, we just use different max values.
>
> So instead of these functions, I suggest to add those max values into
> struct dispc_features.

Ok.

>
>> @@ -2633,7 +2757,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>>       timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
>>
>>       if (dss_mgr_is_lcd(channel))
>> -             timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
>> +             timings_ok =  timings_ok &&
>> +                     dispc.feat->lcd_timings_ok(timings->hsw,
>>                                               timings->hfp, timings->hbp,
>>                                               timings->vsw, timings->vfp,
>>                                               timings->vbp);
>> @@ -2641,6 +2766,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>>       return timings_ok;
>>  }
>>
>> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
>> +{
>> +     u32 timing_h, timing_v;
>> +
>> +     timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
>> +                     FLD_VAL(hbp-1, 27, 20);
>> +     timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
>> +                     FLD_VAL(vbp, 27, 20);
>> +
>> +     dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
>> +     dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
>> +}
>> +
>> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
>> +{
>> +     u32 timing_h, timing_v;
>> +
>> +     timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
>> +                     FLD_VAL(hbp-1, 31, 20);
>> +     timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
>> +                     FLD_VAL(vbp, 31, 20);
>> +
>> +     dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
>> +     dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
>> +}
>
> Same thing here. The code is the same, only the bit fields are larger.
>
>  Tomi
>
ok


-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-08 13:13         ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-08 13:13 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Wed, Aug 8, 2012 at 6:06 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Wed, 2012-08-08 at 17:07 +0530, Chandrabhanu Mahapatra wrote:
>> All the cpu_is checks have been moved to dispc_init_features function providing
>> a much more generic and cleaner interface. The OMAP version and revision
>> specific functions are initialized by dispc_features structure local to dispc.c.
>>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dispc.c |  476 ++++++++++++++++++++++++++-------------
>>  1 file changed, 315 insertions(+), 161 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
>> index 5b289c5..7e0b080 100644
>> --- a/drivers/video/omap2/dss/dispc.c
>> +++ b/drivers/video/omap2/dss/dispc.c
>> @@ -75,12 +75,60 @@ enum omap_burst_size {
>>  #define REG_FLD_MOD(idx, val, start, end)                            \
>>       dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
>>
>> +static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
>> +     const struct omap_video_timings *mgr_timings, u16 width, u16 height,
>> +     u16 out_width, u16 out_height, enum omap_color_mode color_mode,
>> +     bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
>> +     int *decim_y, u16 pos_x, unsigned long *core_clk);
>> +static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
>> +     const struct omap_video_timings *mgr_timings, u16 width, u16 height,
>> +     u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
>> +     bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
>> +     int *decim_y, u16 pos_x, unsigned long *core_clk);
>> +static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
>> +     const struct omap_video_timings *mgr_timings, u16 width, u16 height,
>> +     u16 out_width, u16 out_height,  enum omap_color_mode color_mode,
>> +     bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x,
>> +     int *decim_y, u16 pos_x, unsigned long *core_clk);
>> +
>> +static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
>> +             u16 height, u16 out_width, u16 out_height);
>> +static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
>> +             u16 height, u16 out_width, u16 out_height);
>> +static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
>> +             u16 height, u16 out_width, u16 out_height);
>> +
>> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
>> +             int vsw, int vfp, int vbp);
>> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
>> +             int vsw, int vfp, int vbp);
>> +
>> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
>> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp);
>
> While it's nice to have the initialization of struct dispc_features in
> the beginning of dispc.c, it requires the above prototypes. And in the
> future we may require more. For that reason I think it's better to
> initialize the dispc_features at the end of dispc.c, just above
> dispc_init_features(). This would be kinda similar to how drivers often
> initialize their ops.
>

Yes, this sounds good, but I was just following general order of
structure and function declarations, structures initializations
followed by functions.

>> +static const struct dispc_features omap2_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_24xx,
>> +     .calc_core_clk          =       calc_core_clk_24xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_24xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_24xx,
>> +};
>> +
>> +static const struct dispc_features omap3_2_1_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
>> +     .calc_core_clk          =       calc_core_clk_34xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_24xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_24xx,
>> +};
>> +
>> +static const struct dispc_features omap3_3_0_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
>> +     .calc_core_clk          =       calc_core_clk_34xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_44xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_44xx,
>> +};
>> +
>> +static const struct dispc_features omap4_dispc_features = {
>> +     .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
>> +     .calc_core_clk          =       calc_core_clk_44xx,
>> +     .lcd_timings_ok         =       _dispc_lcd_timings_ok_44xx,
>> +     .set_lcd_timings_hv     =       _dispc_mgr_set_lcd_timings_hv_44xx,
>> +};
>
> During runtime we only require one of these, others can be discarded.
> This can be accomplished with the combination of "__initdata" for these,
> and "__init" for dispc_init_features().
>

The same also applies for all structures in dss_features.c. Just a
thought that __init and __initdata should have also been used there.

> However, because even the one we need will be discarded, we need to copy
> the values. This could be done either by having the dispc_features
> struct inside dispc struct (instead of a pointer), or allocating memory
> for it with devm_kzalloc(). The latter allows us to keep it const, but
> I'm not sure which approach is better (if either).
>

The latter approach seems better as we need to keep it const. I will
try out both anyways.

>> -static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
>> +static bool _dispc_lcd_timings_ok_24xx(int hsw, int hfp, int hbp,
>>               int vsw, int vfp, int vbp)
>>  {
>> -     if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
>> -             if (hsw < 1 || hsw > 64 ||
>> -                             hfp < 1 || hfp > 256 ||
>> -                             hbp < 1 || hbp > 256 ||
>> -                             vsw < 1 || vsw > 64 ||
>> -                             vfp < 0 || vfp > 255 ||
>> -                             vbp < 0 || vbp > 255)
>> -                     return false;
>> -     } else {
>> -             if (hsw < 1 || hsw > 256 ||
>> -                             hfp < 1 || hfp > 4096 ||
>> -                             hbp < 1 || hbp > 4096 ||
>> -                             vsw < 1 || vsw > 256 ||
>> -                             vfp < 0 || vfp > 4095 ||
>> -                             vbp < 0 || vbp > 4095)
>> -                     return false;
>> -     }
>> -
>> +     if (hsw < 1 || hsw > 64 ||
>> +                     hfp < 1 || hfp > 256 ||
>> +                     hbp < 1 || hbp > 256 ||
>> +                     vsw < 1 || vsw > 64  ||
>> +                     vfp < 0 || vfp > 255 ||
>> +                     vbp < 0 || vbp > 255)
>> +             return false;
>> +     return true;
>> +}
>> +static bool _dispc_lcd_timings_ok_44xx(int hsw, int hfp, int hbp,
>> +             int vsw, int vfp, int vbp)
>> +{
>> +     if (hsw < 1 || hsw > 256 ||
>> +                     hfp < 1  || hfp > 4096 ||
>> +                     hbp < 1  || hbp > 4096 ||
>> +                     vsw < 1  || vsw > 256  ||
>> +                     vfp < 0  || vfp > 4095 ||
>> +                     vbp < 0  || vbp > 4095)
>> +             return false;
>>       return true;
>>  }
>
> I think we should use separate functions only when the code is
> different. Here the code is the same, we just use different max values.
>
> So instead of these functions, I suggest to add those max values into
> struct dispc_features.

Ok.

>
>> @@ -2633,7 +2757,8 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>>       timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
>>
>>       if (dss_mgr_is_lcd(channel))
>> -             timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
>> +             timings_ok =  timings_ok &&
>> +                     dispc.feat->lcd_timings_ok(timings->hsw,
>>                                               timings->hfp, timings->hbp,
>>                                               timings->vsw, timings->vfp,
>>                                               timings->vbp);
>> @@ -2641,6 +2766,34 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
>>       return timings_ok;
>>  }
>>
>> +static void _dispc_mgr_set_lcd_timings_hv_24xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
>> +{
>> +     u32 timing_h, timing_v;
>> +
>> +     timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
>> +                     FLD_VAL(hbp-1, 27, 20);
>> +     timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
>> +                     FLD_VAL(vbp, 27, 20);
>> +
>> +     dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
>> +     dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
>> +}
>> +
>> +static void _dispc_mgr_set_lcd_timings_hv_44xx(enum omap_channel channel,
>> +             int hsw, int hfp, int hbp, int vsw, int vfp, int vbp)
>> +{
>> +     u32 timing_h, timing_v;
>> +
>> +     timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
>> +                     FLD_VAL(hbp-1, 31, 20);
>> +     timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
>> +                     FLD_VAL(vbp, 31, 20);
>> +
>> +     dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
>> +     dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
>> +}
>
> Same thing here. The code is the same, only the bit fields are larger.
>
>  Tomi
>
ok


-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-08 11:50     ` Chandrabhanu Mahapatra
@ 2012-08-08 13:16       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-08 13:16 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 7972 bytes --]

On Wed, 2012-08-08 at 17:08 +0530, Chandrabhanu Mahapatra wrote:
> 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
> functions are initialized by dss_features structure local to dss.c.

Most of the comments for the dispc patch apply also to this patch.

> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c |  154 ++++++++++++++++++++++++++++++-----------
>  1 file changed, 114 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..f5971ac 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -65,6 +65,20 @@ struct dss_reg {
>  static int dss_runtime_get(void);
>  static void dss_runtime_put(void);
>  
> +static bool check_dss_cinfo_fck(void);
> +static bool check_dss_cinfo_fck_34xx(void);
> +
> +static int dss_get_clk_24xx(struct clk *clk);
> +static int dss_get_clk_3xxx(struct clk *clk);
> +static int dss_get_clk_44xx(struct clk *clk);
> +
> +struct dss_features {
> +	u16 fck_div_max;
> +	int factor;
> +	bool (*check_cinfo_fck) (void);
> +	int (*get_clk) (struct clk *clk);
> +};
> +
>  static struct {
>  	struct platform_device *pdev;
>  	void __iomem    *base;
> @@ -83,6 +97,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_features *feat;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -91,6 +107,34 @@ static const char * const dss_generic_clk_source_names[] = {
>  	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
>  };
>  
> +static const struct dss_features omap2_dss_features = {
> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck,
> +	.get_clk		=	dss_get_clk_24xx,
> +};
> +
> +static const struct dss_features omap34_dss_features = {
> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck_34xx,
> +	.get_clk		=	dss_get_clk_3xxx,
> +};
> +
> +static const struct dss_features omap36_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck,
> +	.get_clk		=	dss_get_clk_3xxx,
> +};
> +
> +static const struct dss_features omap4_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck,
> +	.get_clk		=	dss_get_clk_44xx,
> +};
> +
>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>  {
>  	__raw_writel(val, dss.base + idx.idx);
> @@ -236,7 +280,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> -
>  void dss_dump_clocks(struct seq_file *s)
>  {
>  	unsigned long dpll4_ck_rate;
> @@ -259,18 +302,10 @@ void dss_dump_clocks(struct seq_file *s)
>  
>  		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>  
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> -		else
> -			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> +		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
> +				fclk_name, fclk_real_name, dpll4_ck_rate,
> +				dpll4_ck_rate / dpll4_m4_ck_rate,
> +				dss.feat->factor, fclk_rate);
>  	} else {
>  		seq_printf(s, "%s (%s) = %lu\n",
>  				fclk_name, fclk_real_name,
> @@ -461,6 +496,25 @@ unsigned long dss_get_dpll4_rate(void)
>  		return 0;
>  }
>  
> +static bool check_dss_cinfo_fck_34xx(void)
> +{
> +	unsigned long prate = dss_get_dpll4_rate();
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (prate == dss.cache_prate || dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;
> +}
> +
> +static bool check_dss_cinfo_fck(void)
> +{
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;

Often code like this is cleaner written as:

	return dss.cache_dss_cinfo.fck == fck;

> +}
> +
>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  		struct dispc_clock_info *dispc_cinfo)
>  {
> @@ -470,7 +524,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	unsigned long fck, max_dss_fck;
>  
> -	u16 fck_div, fck_div_max = 16;
> +	u16 fck_div;
>  
>  	int match = 0;
>  	int min_fck_per_pck;
> @@ -479,10 +533,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
> -	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && dss.feat->check_cinfo_fck()) {

This change, and the check_cinfo_fck() doesn't look correct. I mean,
looking at the code, I think it does the same thing as the old code, but
the line above does look very confusing =). Okay, the original code also
looks confusing.

I don't think the original code is even correct. I think it should
include omap4 also in the prate check... And why does it have || instead
of &&? Shouldn't we check both the prate _and_ the fck, instead of just
either one of those... Who writes this stuff without any clarifying
comments! (I think I wrote the code)

If I'm not mistaken, the whole cpu check could be just discarded. On
OMAP2, where prate does not exist/matter, prate should be always 0. If
it's always 0 in the dss.cache_prate also, we can compare them without
any cpu checks.

Can you verify this, and if I'm right, just get rid of the cpu check
there, and we don't even need the feat thing here.

>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;
> @@ -519,13 +570,10 @@ retry:
>  
>  		goto found;
>  	} else {
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			fck_div_max = 32;
> -
> -		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
> +		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>  			struct dispc_clock_info cur_dispc;
>  
> -			if (fck_div_max == 32)
> +			if (dss.feat->fck_div_max == 32)
>  				fck = prate / fck_div;
>  			else
>  				fck = prate / fck_div * 2;

Hmm, I think this one should use the "factor" field for the multiply.

> @@ -619,6 +667,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
>  	return REG_GET(DSS_CONTROL, 15, 15);
>  }
>  
> +static int dss_get_clk_24xx(struct clk *clk)
> +{
> +	clk = NULL;
> +	return true;
> +}
> +
> +static int dss_get_clk_3xxx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll4_m4_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll4_m4_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}
> +
> +static int dss_get_clk_44xx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll_per_m5x2_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll_per_m5x2_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}

These are almost the same functions. Rather than having separate
functions, perhaps add the clock name into the feat struct. And NULL for
omap2.

The clock name shouldn't really even be in dss, it should come as
parameter, or even better, we wouldn't need it an we could use the clk
framework without this clock. But that was not possible the last time I
looked at it, so let's have it in dss feat struct for now. 

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-08 13:16       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-08 13:16 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 7972 bytes --]

On Wed, 2012-08-08 at 17:08 +0530, Chandrabhanu Mahapatra wrote:
> 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
> functions are initialized by dss_features structure local to dss.c.

Most of the comments for the dispc patch apply also to this patch.

> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c |  154 ++++++++++++++++++++++++++++++-----------
>  1 file changed, 114 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..f5971ac 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -65,6 +65,20 @@ struct dss_reg {
>  static int dss_runtime_get(void);
>  static void dss_runtime_put(void);
>  
> +static bool check_dss_cinfo_fck(void);
> +static bool check_dss_cinfo_fck_34xx(void);
> +
> +static int dss_get_clk_24xx(struct clk *clk);
> +static int dss_get_clk_3xxx(struct clk *clk);
> +static int dss_get_clk_44xx(struct clk *clk);
> +
> +struct dss_features {
> +	u16 fck_div_max;
> +	int factor;
> +	bool (*check_cinfo_fck) (void);
> +	int (*get_clk) (struct clk *clk);
> +};
> +
>  static struct {
>  	struct platform_device *pdev;
>  	void __iomem    *base;
> @@ -83,6 +97,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_features *feat;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -91,6 +107,34 @@ static const char * const dss_generic_clk_source_names[] = {
>  	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
>  };
>  
> +static const struct dss_features omap2_dss_features = {
> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck,
> +	.get_clk		=	dss_get_clk_24xx,
> +};
> +
> +static const struct dss_features omap34_dss_features = {
> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck_34xx,
> +	.get_clk		=	dss_get_clk_3xxx,
> +};
> +
> +static const struct dss_features omap36_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck,
> +	.get_clk		=	dss_get_clk_3xxx,
> +};
> +
> +static const struct dss_features omap4_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.check_cinfo_fck	=	check_dss_cinfo_fck,
> +	.get_clk		=	dss_get_clk_44xx,
> +};
> +
>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>  {
>  	__raw_writel(val, dss.base + idx.idx);
> @@ -236,7 +280,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> -
>  void dss_dump_clocks(struct seq_file *s)
>  {
>  	unsigned long dpll4_ck_rate;
> @@ -259,18 +302,10 @@ void dss_dump_clocks(struct seq_file *s)
>  
>  		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>  
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> -		else
> -			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> +		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
> +				fclk_name, fclk_real_name, dpll4_ck_rate,
> +				dpll4_ck_rate / dpll4_m4_ck_rate,
> +				dss.feat->factor, fclk_rate);
>  	} else {
>  		seq_printf(s, "%s (%s) = %lu\n",
>  				fclk_name, fclk_real_name,
> @@ -461,6 +496,25 @@ unsigned long dss_get_dpll4_rate(void)
>  		return 0;
>  }
>  
> +static bool check_dss_cinfo_fck_34xx(void)
> +{
> +	unsigned long prate = dss_get_dpll4_rate();
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (prate == dss.cache_prate || dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;
> +}
> +
> +static bool check_dss_cinfo_fck(void)
> +{
> +	unsigned long fck = clk_get_rate(dss.dss_clk);
> +
> +	if (dss.cache_dss_cinfo.fck == fck)
> +		return true;
> +	return false;

Often code like this is cleaner written as:

	return dss.cache_dss_cinfo.fck == fck;

> +}
> +
>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  		struct dispc_clock_info *dispc_cinfo)
>  {
> @@ -470,7 +524,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	unsigned long fck, max_dss_fck;
>  
> -	u16 fck_div, fck_div_max = 16;
> +	u16 fck_div;
>  
>  	int match = 0;
>  	int min_fck_per_pck;
> @@ -479,10 +533,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
> -	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && dss.feat->check_cinfo_fck()) {

This change, and the check_cinfo_fck() doesn't look correct. I mean,
looking at the code, I think it does the same thing as the old code, but
the line above does look very confusing =). Okay, the original code also
looks confusing.

I don't think the original code is even correct. I think it should
include omap4 also in the prate check... And why does it have || instead
of &&? Shouldn't we check both the prate _and_ the fck, instead of just
either one of those... Who writes this stuff without any clarifying
comments! (I think I wrote the code)

If I'm not mistaken, the whole cpu check could be just discarded. On
OMAP2, where prate does not exist/matter, prate should be always 0. If
it's always 0 in the dss.cache_prate also, we can compare them without
any cpu checks.

Can you verify this, and if I'm right, just get rid of the cpu check
there, and we don't even need the feat thing here.

>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;
> @@ -519,13 +570,10 @@ retry:
>  
>  		goto found;
>  	} else {
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			fck_div_max = 32;
> -
> -		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
> +		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>  			struct dispc_clock_info cur_dispc;
>  
> -			if (fck_div_max == 32)
> +			if (dss.feat->fck_div_max == 32)
>  				fck = prate / fck_div;
>  			else
>  				fck = prate / fck_div * 2;

Hmm, I think this one should use the "factor" field for the multiply.

> @@ -619,6 +667,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
>  	return REG_GET(DSS_CONTROL, 15, 15);
>  }
>  
> +static int dss_get_clk_24xx(struct clk *clk)
> +{
> +	clk = NULL;
> +	return true;
> +}
> +
> +static int dss_get_clk_3xxx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll4_m4_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll4_m4_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}
> +
> +static int dss_get_clk_44xx(struct clk *clk)
> +{
> +	clk = clk_get(NULL, "dpll_per_m5x2_ck");
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get dpll_per_m5x2_ck\n");
> +		return PTR_ERR(clk);
> +	}
> +	return true;
> +}

These are almost the same functions. Rather than having separate
functions, perhaps add the clock name into the feat struct. And NULL for
omap2.

The clock name shouldn't really even be in dss, it should come as
parameter, or even better, we wouldn't need it an we could use the clk
framework without this clock. But that was not possible the last time I
looked at it, so let's have it in dss feat struct for now. 

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-08 13:13         ` Mahapatra, Chandrabhanu
@ 2012-08-08 13:25           ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-08 13:25 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1373 bytes --]

On Wed, 2012-08-08 at 18:31 +0530, Mahapatra, Chandrabhanu wrote:

> Yes, this sounds good, but I was just following general order of
> structure and function declarations, structures initializations
> followed by functions.

Yep, it's a good rule. But there are exceptions when we'll get bloated
code by following the rule =).

> > During runtime we only require one of these, others can be discarded.
> > This can be accomplished with the combination of "__initdata" for these,
> > and "__init" for dispc_init_features().
> >
> 
> The same also applies for all structures in dss_features.c. Just a
> thought that __init and __initdata should have also been used there.

I agree. We should also see what things we can move from dss_features.c
into dss.c, dispc.c, etc. Some things in dss_features are quite global,
but some are really used only in one place in one file.

Although this also makes me wonder, is it better to have all the
hardware version information for all DSS modules in one place, as we
tried with dss_features, or is it better to have the HW information in
the respective DSS submodule, as you're doing with this patch.

Both have benefits. Even though with the latter method there's no one
place to look for DSS HW feature differences, I think it'll still give
us cleaner code. So let's continue on this track.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-08 13:25           ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-08 13:25 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1373 bytes --]

On Wed, 2012-08-08 at 18:31 +0530, Mahapatra, Chandrabhanu wrote:

> Yes, this sounds good, but I was just following general order of
> structure and function declarations, structures initializations
> followed by functions.

Yep, it's a good rule. But there are exceptions when we'll get bloated
code by following the rule =).

> > During runtime we only require one of these, others can be discarded.
> > This can be accomplished with the combination of "__initdata" for these,
> > and "__init" for dispc_init_features().
> >
> 
> The same also applies for all structures in dss_features.c. Just a
> thought that __init and __initdata should have also been used there.

I agree. We should also see what things we can move from dss_features.c
into dss.c, dispc.c, etc. Some things in dss_features are quite global,
but some are really used only in one place in one file.

Although this also makes me wonder, is it better to have all the
hardware version information for all DSS modules in one place, as we
tried with dss_features, or is it better to have the HW information in
the respective DSS submodule, as you're doing with this patch.

Both have benefits. Even though with the latter method there's no one
place to look for DSS HW feature differences, I think it'll still give
us cleaner code. So let's continue on this track.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-08 13:16       ` Tomi Valkeinen
@ 2012-08-09 11:51         ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-09 11:39 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Wed, Aug 8, 2012 at 6:46 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Wed, 2012-08-08 at 17:08 +0530, Chandrabhanu Mahapatra wrote:
>> 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
>> functions are initialized by dss_features structure local to dss.c.
>
> Most of the comments for the dispc patch apply also to this patch.

Yes, both do almost the same thing but on different files. Any
suggestions if please!

>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dss.c |  154 ++++++++++++++++++++++++++++++-----------
>>  1 file changed, 114 insertions(+), 40 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 7b1c6ac..f5971ac 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -65,6 +65,20 @@ struct dss_reg {
>>  static int dss_runtime_get(void);
>>  static void dss_runtime_put(void);
>>
>> +static bool check_dss_cinfo_fck(void);
>> +static bool check_dss_cinfo_fck_34xx(void);
>> +
>> +static int dss_get_clk_24xx(struct clk *clk);
>> +static int dss_get_clk_3xxx(struct clk *clk);
>> +static int dss_get_clk_44xx(struct clk *clk);
>> +
>> +struct dss_features {
>> +     u16 fck_div_max;
>> +     int factor;
>> +     bool (*check_cinfo_fck) (void);
>> +     int (*get_clk) (struct clk *clk);
>> +};
>> +
>>  static struct {
>>       struct platform_device *pdev;
>>       void __iomem    *base;
>> @@ -83,6 +97,8 @@ static struct {
>>
>>       bool            ctx_valid;
>>       u32             ctx[DSS_SZ_REGS / sizeof(u32)];
>> +
>> +     const struct dss_features *feat;
>>  } dss;
>>
>>  static const char * const dss_generic_clk_source_names[] = {
>> @@ -91,6 +107,34 @@ static const char * const dss_generic_clk_source_names[] = {
>>       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCK",
>>  };
>>
>> +static const struct dss_features omap2_dss_features = {
>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck,
>> +     .get_clk                =       dss_get_clk_24xx,
>> +};
>> +
>> +static const struct dss_features omap34_dss_features = {
>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck_34xx,
>> +     .get_clk                =       dss_get_clk_3xxx,
>> +};
>> +
>> +static const struct dss_features omap36_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck,
>> +     .get_clk                =       dss_get_clk_3xxx,
>> +};
>> +
>> +static const struct dss_features omap4_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck,
>> +     .get_clk                =       dss_get_clk_44xx,
>> +};
>> +

In my opinion these structures should also be initialized with
__initdata and dss_init_features should be __init as dss_features
pointer should be used as like in dispc.c to make the data constant.
But these structures are better placed at top of the file as it highly
unlikely in dss.c that new functions come in and so function
prototypes.

>>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>>  {
>>       __raw_writel(val, dss.base + idx.idx);
>> @@ -236,7 +280,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>>       return dss_generic_clk_source_names[clk_src];
>>  }
>>
>> -
>>  void dss_dump_clocks(struct seq_file *s)
>>  {
>>       unsigned long dpll4_ck_rate;
>> @@ -259,18 +302,10 @@ void dss_dump_clocks(struct seq_file *s)
>>
>>               seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>>
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> -             else
>> -                     seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> +             seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
>> +                             fclk_name, fclk_real_name, dpll4_ck_rate,
>> +                             dpll4_ck_rate / dpll4_m4_ck_rate,
>> +                             dss.feat->factor, fclk_rate);
>>       } else {
>>               seq_printf(s, "%s (%s) = %lu\n",
>>                               fclk_name, fclk_real_name,
>> @@ -461,6 +496,25 @@ unsigned long dss_get_dpll4_rate(void)
>>               return 0;
>>  }
>>
>> +static bool check_dss_cinfo_fck_34xx(void)
>> +{
>> +     unsigned long prate = dss_get_dpll4_rate();
>> +     unsigned long fck = clk_get_rate(dss.dss_clk);
>> +
>> +     if (prate == dss.cache_prate || dss.cache_dss_cinfo.fck == fck)
>> +             return true;
>> +     return false;
>> +}
>> +
>> +static bool check_dss_cinfo_fck(void)
>> +{
>> +     unsigned long fck = clk_get_rate(dss.dss_clk);
>> +
>> +     if (dss.cache_dss_cinfo.fck == fck)
>> +             return true;
>> +     return false;
>
> Often code like this is cleaner written as:
>
>         return dss.cache_dss_cinfo.fck == fck;
>

ok.

>> +}
>> +
>>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>               struct dispc_clock_info *dispc_cinfo)
>>  {
>> @@ -470,7 +524,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>
>>       unsigned long fck, max_dss_fck;
>>
>> -     u16 fck_div, fck_div_max = 16;
>> +     u16 fck_div;
>>
>>       int match = 0;
>>       int min_fck_per_pck;
>> @@ -479,10 +533,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>
>>       max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>>
>> -     fck = clk_get_rate(dss.dss_clk);
>> -     if (req_pck == dss.cache_req_pck &&
>> -                     ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
>> -                      dss.cache_dss_cinfo.fck == fck)) {
>> +     if (req_pck == dss.cache_req_pck && dss.feat->check_cinfo_fck()) {
>
> This change, and the check_cinfo_fck() doesn't look correct. I mean,
> looking at the code, I think it does the same thing as the old code, but
> the line above does look very confusing =). Okay, the original code also
> looks confusing.
>
> I don't think the original code is even correct. I think it should
> include omap4 also in the prate check... And why does it have || instead
> of &&? Shouldn't we check both the prate _and_ the fck, instead of just
> either one of those... Who writes this stuff without any clarifying
> comments! (I think I wrote the code)
>
> If I'm not mistaken, the whole cpu check could be just discarded. On
> OMAP2, where prate does not exist/matter, prate should be always 0. If
> it's always 0 in the dss.cache_prate also, we can compare them without
> any cpu checks.
>
> Can you verify this, and if I'm right, just get rid of the cpu check
> there, and we don't even need the feat thing here.
>

Yes, you are right the whole cpu_is check should be discarded. Only in
OMAP2 in dss_get_clocks() the dss.dpll4_m4_ck will be NULL and so does
prate. In other cases it will initialized including OMAP4. But I am
still in doubt whether it should be be || or a && operation, most
probably &&.

>>               DSSDBG("dispc clock info found from cache.\n");
>>               *dss_cinfo = dss.cache_dss_cinfo;
>>               *dispc_cinfo = dss.cache_dispc_cinfo;
>> @@ -519,13 +570,10 @@ retry:
>>
>>               goto found;
>>       } else {
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     fck_div_max = 32;
>> -
>> -             for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
>> +             for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>>                       struct dispc_clock_info cur_dispc;
>>
>> -                     if (fck_div_max == 32)
>> +                     if (dss.feat->fck_div_max == 32)
>>                               fck = prate / fck_div;
>>                       else
>>                               fck = prate / fck_div * 2;
>
> Hmm, I think this one should use the "factor" field for the multiply.

Yes.

>
>> @@ -619,6 +667,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
>>       return REG_GET(DSS_CONTROL, 15, 15);
>>  }
>>
>> +static int dss_get_clk_24xx(struct clk *clk)
>> +{
>> +     clk = NULL;
>> +     return true;
>> +}
>> +
>> +static int dss_get_clk_3xxx(struct clk *clk)
>> +{
>> +     clk = clk_get(NULL, "dpll4_m4_ck");
>> +     if (IS_ERR(clk)) {
>> +             DSSERR("Failed to get dpll4_m4_ck\n");
>> +             return PTR_ERR(clk);
>> +     }
>> +     return true;
>> +}
>> +
>> +static int dss_get_clk_44xx(struct clk *clk)
>> +{
>> +     clk = clk_get(NULL, "dpll_per_m5x2_ck");
>> +     if (IS_ERR(clk)) {
>> +             DSSERR("Failed to get dpll_per_m5x2_ck\n");
>> +             return PTR_ERR(clk);
>> +     }
>> +     return true;
>> +}
>
> These are almost the same functions. Rather than having separate
> functions, perhaps add the clock name into the feat struct. And NULL for
> omap2.
>
> The clock name shouldn't really even be in dss, it should come as
> parameter, or even better, we wouldn't need it an we could use the clk
> framework without this clock. But that was not possible the last time I
> looked at it, so let's have it in dss feat struct for now.
>
>  Tomi
>

ok.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-09 11:51         ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-09 11:51 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Wed, Aug 8, 2012 at 6:46 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Wed, 2012-08-08 at 17:08 +0530, Chandrabhanu Mahapatra wrote:
>> 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
>> functions are initialized by dss_features structure local to dss.c.
>
> Most of the comments for the dispc patch apply also to this patch.

Yes, both do almost the same thing but on different files. Any
suggestions if please!

>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dss.c |  154 ++++++++++++++++++++++++++++++-----------
>>  1 file changed, 114 insertions(+), 40 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 7b1c6ac..f5971ac 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -65,6 +65,20 @@ struct dss_reg {
>>  static int dss_runtime_get(void);
>>  static void dss_runtime_put(void);
>>
>> +static bool check_dss_cinfo_fck(void);
>> +static bool check_dss_cinfo_fck_34xx(void);
>> +
>> +static int dss_get_clk_24xx(struct clk *clk);
>> +static int dss_get_clk_3xxx(struct clk *clk);
>> +static int dss_get_clk_44xx(struct clk *clk);
>> +
>> +struct dss_features {
>> +     u16 fck_div_max;
>> +     int factor;
>> +     bool (*check_cinfo_fck) (void);
>> +     int (*get_clk) (struct clk *clk);
>> +};
>> +
>>  static struct {
>>       struct platform_device *pdev;
>>       void __iomem    *base;
>> @@ -83,6 +97,8 @@ static struct {
>>
>>       bool            ctx_valid;
>>       u32             ctx[DSS_SZ_REGS / sizeof(u32)];
>> +
>> +     const struct dss_features *feat;
>>  } dss;
>>
>>  static const char * const dss_generic_clk_source_names[] = {
>> @@ -91,6 +107,34 @@ static const char * const dss_generic_clk_source_names[] = {
>>       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCK",
>>  };
>>
>> +static const struct dss_features omap2_dss_features = {
>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck,
>> +     .get_clk                =       dss_get_clk_24xx,
>> +};
>> +
>> +static const struct dss_features omap34_dss_features = {
>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck_34xx,
>> +     .get_clk                =       dss_get_clk_3xxx,
>> +};
>> +
>> +static const struct dss_features omap36_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck,
>> +     .get_clk                =       dss_get_clk_3xxx,
>> +};
>> +
>> +static const struct dss_features omap4_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .check_cinfo_fck        =       check_dss_cinfo_fck,
>> +     .get_clk                =       dss_get_clk_44xx,
>> +};
>> +

In my opinion these structures should also be initialized with
__initdata and dss_init_features should be __init as dss_features
pointer should be used as like in dispc.c to make the data constant.
But these structures are better placed at top of the file as it highly
unlikely in dss.c that new functions come in and so function
prototypes.

>>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>>  {
>>       __raw_writel(val, dss.base + idx.idx);
>> @@ -236,7 +280,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>>       return dss_generic_clk_source_names[clk_src];
>>  }
>>
>> -
>>  void dss_dump_clocks(struct seq_file *s)
>>  {
>>       unsigned long dpll4_ck_rate;
>> @@ -259,18 +302,10 @@ void dss_dump_clocks(struct seq_file *s)
>>
>>               seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>>
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> -             else
>> -                     seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> +             seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
>> +                             fclk_name, fclk_real_name, dpll4_ck_rate,
>> +                             dpll4_ck_rate / dpll4_m4_ck_rate,
>> +                             dss.feat->factor, fclk_rate);
>>       } else {
>>               seq_printf(s, "%s (%s) = %lu\n",
>>                               fclk_name, fclk_real_name,
>> @@ -461,6 +496,25 @@ unsigned long dss_get_dpll4_rate(void)
>>               return 0;
>>  }
>>
>> +static bool check_dss_cinfo_fck_34xx(void)
>> +{
>> +     unsigned long prate = dss_get_dpll4_rate();
>> +     unsigned long fck = clk_get_rate(dss.dss_clk);
>> +
>> +     if (prate = dss.cache_prate || dss.cache_dss_cinfo.fck = fck)
>> +             return true;
>> +     return false;
>> +}
>> +
>> +static bool check_dss_cinfo_fck(void)
>> +{
>> +     unsigned long fck = clk_get_rate(dss.dss_clk);
>> +
>> +     if (dss.cache_dss_cinfo.fck = fck)
>> +             return true;
>> +     return false;
>
> Often code like this is cleaner written as:
>
>         return dss.cache_dss_cinfo.fck = fck;
>

ok.

>> +}
>> +
>>  int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>               struct dispc_clock_info *dispc_cinfo)
>>  {
>> @@ -470,7 +524,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>
>>       unsigned long fck, max_dss_fck;
>>
>> -     u16 fck_div, fck_div_max = 16;
>> +     u16 fck_div;
>>
>>       int match = 0;
>>       int min_fck_per_pck;
>> @@ -479,10 +533,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>
>>       max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>>
>> -     fck = clk_get_rate(dss.dss_clk);
>> -     if (req_pck = dss.cache_req_pck &&
>> -                     ((cpu_is_omap34xx() && prate = dss.cache_prate) ||
>> -                      dss.cache_dss_cinfo.fck = fck)) {
>> +     if (req_pck = dss.cache_req_pck && dss.feat->check_cinfo_fck()) {
>
> This change, and the check_cinfo_fck() doesn't look correct. I mean,
> looking at the code, I think it does the same thing as the old code, but
> the line above does look very confusing =). Okay, the original code also
> looks confusing.
>
> I don't think the original code is even correct. I think it should
> include omap4 also in the prate check... And why does it have || instead
> of &&? Shouldn't we check both the prate _and_ the fck, instead of just
> either one of those... Who writes this stuff without any clarifying
> comments! (I think I wrote the code)
>
> If I'm not mistaken, the whole cpu check could be just discarded. On
> OMAP2, where prate does not exist/matter, prate should be always 0. If
> it's always 0 in the dss.cache_prate also, we can compare them without
> any cpu checks.
>
> Can you verify this, and if I'm right, just get rid of the cpu check
> there, and we don't even need the feat thing here.
>

Yes, you are right the whole cpu_is check should be discarded. Only in
OMAP2 in dss_get_clocks() the dss.dpll4_m4_ck will be NULL and so does
prate. In other cases it will initialized including OMAP4. But I am
still in doubt whether it should be be || or a && operation, most
probably &&.

>>               DSSDBG("dispc clock info found from cache.\n");
>>               *dss_cinfo = dss.cache_dss_cinfo;
>>               *dispc_cinfo = dss.cache_dispc_cinfo;
>> @@ -519,13 +570,10 @@ retry:
>>
>>               goto found;
>>       } else {
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     fck_div_max = 32;
>> -
>> -             for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
>> +             for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>>                       struct dispc_clock_info cur_dispc;
>>
>> -                     if (fck_div_max = 32)
>> +                     if (dss.feat->fck_div_max = 32)
>>                               fck = prate / fck_div;
>>                       else
>>                               fck = prate / fck_div * 2;
>
> Hmm, I think this one should use the "factor" field for the multiply.

Yes.

>
>> @@ -619,6 +667,32 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
>>       return REG_GET(DSS_CONTROL, 15, 15);
>>  }
>>
>> +static int dss_get_clk_24xx(struct clk *clk)
>> +{
>> +     clk = NULL;
>> +     return true;
>> +}
>> +
>> +static int dss_get_clk_3xxx(struct clk *clk)
>> +{
>> +     clk = clk_get(NULL, "dpll4_m4_ck");
>> +     if (IS_ERR(clk)) {
>> +             DSSERR("Failed to get dpll4_m4_ck\n");
>> +             return PTR_ERR(clk);
>> +     }
>> +     return true;
>> +}
>> +
>> +static int dss_get_clk_44xx(struct clk *clk)
>> +{
>> +     clk = clk_get(NULL, "dpll_per_m5x2_ck");
>> +     if (IS_ERR(clk)) {
>> +             DSSERR("Failed to get dpll_per_m5x2_ck\n");
>> +             return PTR_ERR(clk);
>> +     }
>> +     return true;
>> +}
>
> These are almost the same functions. Rather than having separate
> functions, perhaps add the clock name into the feat struct. And NULL for
> omap2.
>
> The clock name shouldn't really even be in dss, it should come as
> parameter, or even better, we wouldn't need it an we could use the clk
> framework without this clock. But that was not possible the last time I
> looked at it, so let's have it in dss feat struct for now.
>
>  Tomi
>

ok.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-08 11:49     ` Chandrabhanu Mahapatra
@ 2012-08-13 12:10       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-13 11:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  428 +++++++++++++++++++++++++--------------
 1 file changed, 273 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..11ca3f9 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int hp_max;
+	int vp_max;
+	int sw_max;
+	int sw_start;
+	int fp_start;
+	int bp_start;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
 	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth =
+				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth =
-				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width == out_width && height == out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,72 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct __initdata dispc_features omap2_dispc_features = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct __initdata dispc_features omap3_2_1_dispc_features = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct __initdata dispc_features omap3_3_0_dispc_features = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct __initdata dispc_features omap4_dispc_features = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	dispc.feat = devm_kzalloc(dev, sizeof(*dispc.feat), GFP_KERNEL);
+	if (!dispc.feat) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		dispc.feat = &omap2_dispc_features;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			dispc.feat = &omap3_2_1_dispc_features;
+		else
+			dispc.feat = &omap3_3_0_dispc_features;
+	} else {
+		dispc.feat = &omap4_dispc_features;
+	}
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3725,6 +3837,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
@@ -3760,6 +3876,8 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
 
 	clk_put(dispc.dss_clk);
 
+	devm_kfree(&dispc.pdev->dev, (void *)dispc.feat);
+
 	return 0;
 }
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-08 11:50     ` Chandrabhanu Mahapatra
@ 2012-08-13 12:11       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-13 11:59 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
 1 file changed, 74 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..6ab236e 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/dma-mapping.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,13 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u16 fck_div_max;
+	int factor;
+	char *clk_name;
+	bool (*check_cinfo_fck) (void);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +91,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +101,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct __initdata dss_features omap2_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct __initdata dss_features omap34_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct __initdata dss_features omap36_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct __initdata dss_features omap4_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__raw_writel(val, dss.base + idx.idx);
@@ -236,7 +270,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +292,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->factor, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +495,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +505,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck == dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck == fck)) {
+	if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
+		dss.cache_dss_cinfo.fck == fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +543,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max == 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->factor;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -633,22 +651,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -704,6 +711,26 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
+	if (!dss.feat) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		dss.feat = &omap2_dss_features;
+	else if (cpu_is_omap34xx())
+		dss.feat = &omap34_dss_features;
+	else if (cpu_is_omap3630())
+		dss.feat = &omap36_dss_features;
+	else
+		dss.feat = &omap4_dss_features;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -750,6 +777,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -772,6 +803,8 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
 
 	dss_put_clocks();
 
+	devm_kfree(&dss.pdev->dev, (void *)dss.feat);
+
 	return 0;
 }
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-13 12:10       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-13 12:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  428 +++++++++++++++++++++++++--------------
 1 file changed, 273 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..11ca3f9 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int hp_max;
+	int vp_max;
+	int sw_max;
+	int sw_start;
+	int fp_start;
+	int bp_start;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
 	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth +				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth -				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width = out_width && height = out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,72 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct __initdata dispc_features omap2_dispc_features = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct __initdata dispc_features omap3_2_1_dispc_features = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct __initdata dispc_features omap3_3_0_dispc_features = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct __initdata dispc_features omap4_dispc_features = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	dispc.feat = devm_kzalloc(dev, sizeof(*dispc.feat), GFP_KERNEL);
+	if (!dispc.feat) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		dispc.feat = &omap2_dispc_features;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			dispc.feat = &omap3_2_1_dispc_features;
+		else
+			dispc.feat = &omap3_3_0_dispc_features;
+	} else {
+		dispc.feat = &omap4_dispc_features;
+	}
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3725,6 +3837,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
@@ -3760,6 +3876,8 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
 
 	clk_put(dispc.dss_clk);
 
+	devm_kfree(&dispc.pdev->dev, (void *)dispc.feat);
+
 	return 0;
 }
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-13 12:11       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-13 12:11 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
 1 file changed, 74 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..6ab236e 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/dma-mapping.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,13 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u16 fck_div_max;
+	int factor;
+	char *clk_name;
+	bool (*check_cinfo_fck) (void);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +91,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +101,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct __initdata dss_features omap2_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct __initdata dss_features omap34_dss_features = {
+	.fck_div_max		=	16,
+	.factor			=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct __initdata dss_features omap36_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct __initdata dss_features omap4_dss_features = {
+	.fck_div_max		=	32,
+	.factor			=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__raw_writel(val, dss.base + idx.idx);
@@ -236,7 +270,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +292,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->factor, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +495,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +505,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck = dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate = dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck = fck)) {
+	if (req_pck = dss.cache_req_pck && prate = dss.cache_prate &&
+		dss.cache_dss_cinfo.fck = fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +543,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max = 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->factor;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -633,22 +651,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -704,6 +711,26 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
+	if (!dss.feat) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		dss.feat = &omap2_dss_features;
+	else if (cpu_is_omap34xx())
+		dss.feat = &omap34_dss_features;
+	else if (cpu_is_omap3630())
+		dss.feat = &omap36_dss_features;
+	else
+		dss.feat = &omap4_dss_features;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -750,6 +777,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -772,6 +803,8 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
 
 	dss_put_clocks();
 
+	devm_kfree(&dss.pdev->dev, (void *)dss.feat);
+
 	return 0;
 }
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-13 12:11       ` Chandrabhanu Mahapatra
@ 2012-08-14  9:48         ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14  9:48 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 8283 bytes --]

On Mon, 2012-08-13 at 17:29 +0530, Chandrabhanu Mahapatra wrote:
> 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.

It'd be good to have some version information here. Even just [PATCH v3
3/6] in the subject is good, but of course the best is if there's a
short change log

> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
>  1 file changed, 74 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..6ab236e 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -31,6 +31,7 @@
>  #include <linux/clk.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/dma-mapping.h>

Hmm, what is this for?
 
>  #include <video/omapdss.h>
>  
> @@ -65,6 +66,13 @@ struct dss_reg {
>  static int dss_runtime_get(void);
>  static void dss_runtime_put(void);
>  
> +struct dss_features {
> +	u16 fck_div_max;
> +	int factor;
> +	char *clk_name;
> +	bool (*check_cinfo_fck) (void);
> +};

Is the check_cinfo_fck a leftover from previous versions?

I think "factor" name is too vague. If I remember right, it's some kind
of implicit multiplier for the dss fck. So "dss_fck_multiplier"? You
could check the clock trees to verify what the multiplier exactly was,
and see if you can come up with a better name =).

> +
>  static struct {
>  	struct platform_device *pdev;
>  	void __iomem    *base;
> @@ -83,6 +91,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_features *feat;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -91,6 +101,30 @@ static const char * const dss_generic_clk_source_names[] = {
>  	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
>  };
>  
> +static const struct __initdata dss_features omap2_dss_features = {
> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.clk_name		=	NULL,
> +};

include/linux/init.h says says __initdata should be used like:

static int init_variable __initdata = 0;

And there actually seems to be __initconst also, which I think is the
correct one to use here. Didn't know about that =):

static const char linux_logo[] __initconst = { 0x32, 0x36, ... };

> +static const struct __initdata dss_features omap34_dss_features = {

Perhaps the names could be more consistent. "omap34" doesn't sound like
any omap we have ;). So maybe just omap2xxx, omap34xx, etc, the same way
we have in the cpu_is calls.

> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.clk_name		=	"dpll4_m4_ck",
> +};
> +
> +static const struct __initdata dss_features omap36_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.clk_name		=	"dpll4_m4_ck",
> +};
> +
> +static const struct __initdata dss_features omap4_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.clk_name		=	"dpll_per_m5x2_ck",
> +};
> +
>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>  {
>  	__raw_writel(val, dss.base + idx.idx);
> @@ -236,7 +270,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> -
>  void dss_dump_clocks(struct seq_file *s)
>  {
>  	unsigned long dpll4_ck_rate;
> @@ -259,18 +292,10 @@ void dss_dump_clocks(struct seq_file *s)
>  
>  		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>  
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> -		else
> -			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> +		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
> +				fclk_name, fclk_real_name, dpll4_ck_rate,
> +				dpll4_ck_rate / dpll4_m4_ck_rate,
> +				dss.feat->factor, fclk_rate);
>  	} else {
>  		seq_printf(s, "%s (%s) = %lu\n",
>  				fclk_name, fclk_real_name,
> @@ -470,7 +495,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	unsigned long fck, max_dss_fck;
>  
> -	u16 fck_div, fck_div_max = 16;
> +	u16 fck_div;
>  
>  	int match = 0;
>  	int min_fck_per_pck;
> @@ -480,9 +505,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
>  	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
> +		dss.cache_dss_cinfo.fck == fck) {
>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;
> @@ -519,16 +543,10 @@ retry:
>  
>  		goto found;
>  	} else {
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			fck_div_max = 32;
> -
> -		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
> +		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>  			struct dispc_clock_info cur_dispc;
>  
> -			if (fck_div_max == 32)
> -				fck = prate / fck_div;
> -			else
> -				fck = prate / fck_div * 2;
> +			fck = prate / fck_div * dss.feat->factor;
>  
>  			if (fck > max_dss_fck)
>  				continue;
> @@ -633,22 +651,11 @@ static int dss_get_clocks(void)
>  
>  	dss.dss_clk = clk;
>  
> -	if (cpu_is_omap34xx()) {
> -		clk = clk_get(NULL, "dpll4_m4_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll4_m4_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else if (cpu_is_omap44xx()) {
> -		clk = clk_get(NULL, "dpll_per_m5x2_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll_per_m5x2_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else { /* omap24xx */
> -		clk = NULL;
> +	clk = clk_get(NULL, dss.feat->clk_name);
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get %s\n", dss.feat->clk_name);
> +		r = PTR_ERR(clk);
> +		goto err;
>  	}
>  
>  	dss.dpll4_m4_ck = clk;
> @@ -704,6 +711,26 @@ void dss_debug_dump_clocks(struct seq_file *s)
>  }
>  #endif
>  
> +static int __init dss_init_features(struct device *dev)
> +{
> +	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
> +	if (!dss.feat) {
> +		dev_err(dev, "Failed to allocate local DSS Features\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (cpu_is_omap24xx())
> +		dss.feat = &omap2_dss_features;
> +	else if (cpu_is_omap34xx())
> +		dss.feat = &omap34_dss_features;
> +	else if (cpu_is_omap3630())
> +		dss.feat = &omap36_dss_features;
> +	else
> +		dss.feat = &omap4_dss_features;

Check for omap4 also, and if the cpu is none of the above, return error.

> +
> +	return 0;
> +}
> +
>  /* DSS HW IP initialisation */
>  static int __init omap_dsshw_probe(struct platform_device *pdev)
>  {
> @@ -750,6 +777,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
>  	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
>  	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
>  
> +	r = dss_init_features(&dss.pdev->dev);
> +	if (r)
> +		return r;
> +
>  	rev = dss_read_reg(DSS_REVISION);
>  	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
>  			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
> @@ -772,6 +803,8 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
>  
>  	dss_put_clocks();
>  
> +	devm_kfree(&dss.pdev->dev, (void *)dss.feat);

You don't need to free the memory allocated with devm_kzalloc. The
framework will free it automatically on unload (that's the idea of
devm_* functions).

Otherwise looks good, cleans up nicely the cpu_is_* mess.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-14  9:48         ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14  9:48 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 8283 bytes --]

On Mon, 2012-08-13 at 17:29 +0530, Chandrabhanu Mahapatra wrote:
> 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.

It'd be good to have some version information here. Even just [PATCH v3
3/6] in the subject is good, but of course the best is if there's a
short change log

> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
>  1 file changed, 74 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 7b1c6ac..6ab236e 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -31,6 +31,7 @@
>  #include <linux/clk.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/dma-mapping.h>

Hmm, what is this for?
 
>  #include <video/omapdss.h>
>  
> @@ -65,6 +66,13 @@ struct dss_reg {
>  static int dss_runtime_get(void);
>  static void dss_runtime_put(void);
>  
> +struct dss_features {
> +	u16 fck_div_max;
> +	int factor;
> +	char *clk_name;
> +	bool (*check_cinfo_fck) (void);
> +};

Is the check_cinfo_fck a leftover from previous versions?

I think "factor" name is too vague. If I remember right, it's some kind
of implicit multiplier for the dss fck. So "dss_fck_multiplier"? You
could check the clock trees to verify what the multiplier exactly was,
and see if you can come up with a better name =).

> +
>  static struct {
>  	struct platform_device *pdev;
>  	void __iomem    *base;
> @@ -83,6 +91,8 @@ static struct {
>  
>  	bool		ctx_valid;
>  	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_features *feat;
>  } dss;
>  
>  static const char * const dss_generic_clk_source_names[] = {
> @@ -91,6 +101,30 @@ static const char * const dss_generic_clk_source_names[] = {
>  	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
>  };
>  
> +static const struct __initdata dss_features omap2_dss_features = {
> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.clk_name		=	NULL,
> +};

include/linux/init.h says says __initdata should be used like:

static int init_variable __initdata = 0;

And there actually seems to be __initconst also, which I think is the
correct one to use here. Didn't know about that =):

static const char linux_logo[] __initconst = { 0x32, 0x36, ... };

> +static const struct __initdata dss_features omap34_dss_features = {

Perhaps the names could be more consistent. "omap34" doesn't sound like
any omap we have ;). So maybe just omap2xxx, omap34xx, etc, the same way
we have in the cpu_is calls.

> +	.fck_div_max		=	16,
> +	.factor			=	2,
> +	.clk_name		=	"dpll4_m4_ck",
> +};
> +
> +static const struct __initdata dss_features omap36_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.clk_name		=	"dpll4_m4_ck",
> +};
> +
> +static const struct __initdata dss_features omap4_dss_features = {
> +	.fck_div_max		=	32,
> +	.factor			=	1,
> +	.clk_name		=	"dpll_per_m5x2_ck",
> +};
> +
>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>  {
>  	__raw_writel(val, dss.base + idx.idx);
> @@ -236,7 +270,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>  	return dss_generic_clk_source_names[clk_src];
>  }
>  
> -
>  void dss_dump_clocks(struct seq_file *s)
>  {
>  	unsigned long dpll4_ck_rate;
> @@ -259,18 +292,10 @@ void dss_dump_clocks(struct seq_file *s)
>  
>  		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>  
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> -		else
> -			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
> -					fclk_name, fclk_real_name,
> -					dpll4_ck_rate,
> -					dpll4_ck_rate / dpll4_m4_ck_rate,
> -					fclk_rate);
> +		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
> +				fclk_name, fclk_real_name, dpll4_ck_rate,
> +				dpll4_ck_rate / dpll4_m4_ck_rate,
> +				dss.feat->factor, fclk_rate);
>  	} else {
>  		seq_printf(s, "%s (%s) = %lu\n",
>  				fclk_name, fclk_real_name,
> @@ -470,7 +495,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  
>  	unsigned long fck, max_dss_fck;
>  
> -	u16 fck_div, fck_div_max = 16;
> +	u16 fck_div;
>  
>  	int match = 0;
>  	int min_fck_per_pck;
> @@ -480,9 +505,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>  
>  	fck = clk_get_rate(dss.dss_clk);
> -	if (req_pck == dss.cache_req_pck &&
> -			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
> -			 dss.cache_dss_cinfo.fck == fck)) {
> +	if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
> +		dss.cache_dss_cinfo.fck == fck) {
>  		DSSDBG("dispc clock info found from cache.\n");
>  		*dss_cinfo = dss.cache_dss_cinfo;
>  		*dispc_cinfo = dss.cache_dispc_cinfo;
> @@ -519,16 +543,10 @@ retry:
>  
>  		goto found;
>  	} else {
> -		if (cpu_is_omap3630() || cpu_is_omap44xx())
> -			fck_div_max = 32;
> -
> -		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
> +		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>  			struct dispc_clock_info cur_dispc;
>  
> -			if (fck_div_max == 32)
> -				fck = prate / fck_div;
> -			else
> -				fck = prate / fck_div * 2;
> +			fck = prate / fck_div * dss.feat->factor;
>  
>  			if (fck > max_dss_fck)
>  				continue;
> @@ -633,22 +651,11 @@ static int dss_get_clocks(void)
>  
>  	dss.dss_clk = clk;
>  
> -	if (cpu_is_omap34xx()) {
> -		clk = clk_get(NULL, "dpll4_m4_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll4_m4_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else if (cpu_is_omap44xx()) {
> -		clk = clk_get(NULL, "dpll_per_m5x2_ck");
> -		if (IS_ERR(clk)) {
> -			DSSERR("Failed to get dpll_per_m5x2_ck\n");
> -			r = PTR_ERR(clk);
> -			goto err;
> -		}
> -	} else { /* omap24xx */
> -		clk = NULL;
> +	clk = clk_get(NULL, dss.feat->clk_name);
> +	if (IS_ERR(clk)) {
> +		DSSERR("Failed to get %s\n", dss.feat->clk_name);
> +		r = PTR_ERR(clk);
> +		goto err;
>  	}
>  
>  	dss.dpll4_m4_ck = clk;
> @@ -704,6 +711,26 @@ void dss_debug_dump_clocks(struct seq_file *s)
>  }
>  #endif
>  
> +static int __init dss_init_features(struct device *dev)
> +{
> +	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
> +	if (!dss.feat) {
> +		dev_err(dev, "Failed to allocate local DSS Features\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (cpu_is_omap24xx())
> +		dss.feat = &omap2_dss_features;
> +	else if (cpu_is_omap34xx())
> +		dss.feat = &omap34_dss_features;
> +	else if (cpu_is_omap3630())
> +		dss.feat = &omap36_dss_features;
> +	else
> +		dss.feat = &omap4_dss_features;

Check for omap4 also, and if the cpu is none of the above, return error.

> +
> +	return 0;
> +}
> +
>  /* DSS HW IP initialisation */
>  static int __init omap_dsshw_probe(struct platform_device *pdev)
>  {
> @@ -750,6 +777,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
>  	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
>  	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
>  
> +	r = dss_init_features(&dss.pdev->dev);
> +	if (r)
> +		return r;
> +
>  	rev = dss_read_reg(DSS_REVISION);
>  	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
>  			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
> @@ -772,6 +803,8 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
>  
>  	dss_put_clocks();
>  
> +	devm_kfree(&dss.pdev->dev, (void *)dss.feat);

You don't need to free the memory allocated with devm_kzalloc. The
framework will free it automatically on unload (that's the idea of
devm_* functions).

Otherwise looks good, cleans up nicely the cpu_is_* mess.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-13 12:10       ` Chandrabhanu Mahapatra
@ 2012-08-14  9:58         ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14  9:58 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 498 bytes --]

On Mon, 2012-08-13 at 17:28 +0530, Chandrabhanu Mahapatra wrote:
> All the cpu_is checks have been moved to dispc_init_features function providing
> a much more generic and cleaner interface. The OMAP version and revision
> specific functions and data are initialized by dispc_features structure which is
> local to dispc.c.

The comments I gave for the dss.c patch apply to this one also, about
devm_free, __initdata, and the names of the feat arrays.

Otherwise, looks good.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-14  9:58         ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14  9:58 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 498 bytes --]

On Mon, 2012-08-13 at 17:28 +0530, Chandrabhanu Mahapatra wrote:
> All the cpu_is checks have been moved to dispc_init_features function providing
> a much more generic and cleaner interface. The OMAP version and revision
> specific functions and data are initialized by dispc_features structure which is
> local to dispc.c.

The comments I gave for the dss.c patch apply to this one also, about
devm_free, __initdata, and the names of the feat arrays.

Otherwise, looks good.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-13 12:10       ` Chandrabhanu Mahapatra
@ 2012-08-14 12:15         ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-14 12:03 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev

> +static const struct __initdata dispc_features omap2_dispc_features = {
> +       .hp_max                 =       256,
> +       .vp_max                 =       255,
> +       .sw_max                 =       64,
> +       .sw_start               =       5,
> +       .fp_start               =       15,
> +       .bp_start               =       27,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_24xx,
> +       .calc_core_clk          =       calc_core_clk_24xx,
> +};
> +
> +static const struct __initdata dispc_features omap3_2_1_dispc_features = {
> +       .hp_max                 =       256,
> +       .vp_max                 =       255,
> +       .sw_max                 =       64,
> +       .sw_start               =       5,
> +       .fp_start               =       15,
> +       .bp_start               =       27,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> +       .calc_core_clk          =       calc_core_clk_34xx,
> +};
> +
> +static const struct __initdata dispc_features omap3_3_0_dispc_features = {
> +       .hp_max                 =       4096,
> +       .vp_max                 =       4095,
> +       .sw_max                 =       256,
> +       .sw_start               =       7,
> +       .fp_start               =       19,
> +       .bp_start               =       31,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> +       .calc_core_clk          =       calc_core_clk_34xx,
> +};
> +
> +static const struct __initdata dispc_features omap4_dispc_features = {
> +       .hp_max                 =       4096,
> +       .vp_max                 =       4095,
> +       .sw_max                 =       256,
> +       .sw_start               =       7,
> +       .fp_start               =       19,
> +       .bp_start               =       31,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
> +       .calc_core_clk          =       calc_core_clk_44xx,
> +};
> +

Here the dispc_features not only mention the omap name but also the
revision like omap3_3_0_dispc_features which initializes data for
OMAP3430_REV_ES3_0 and higher. May be omap34xx_rev3_0_dispc_features
is a better name for this. For others omap44xx_dispc_features kind of
name should be ok without revision number being mentioned. What d you
say?

> +static int __init dispc_init_features(struct device *dev)
> +{
> +       dispc.feat = devm_kzalloc(dev, sizeof(*dispc.feat), GFP_KERNEL);
> +       if (!dispc.feat) {
> +               dev_err(dev, "Failed to allocate DISPC Features\n");
> +               return -ENOMEM;
> +       }
> +
> +       if (cpu_is_omap24xx()) {
> +               dispc.feat = &omap2_dispc_features;
> +       } else if (cpu_is_omap34xx()) {
> +               if (omap_rev() < OMAP3430_REV_ES3_0)
> +                       dispc.feat = &omap3_2_1_dispc_features;
> +               else
> +                       dispc.feat = &omap3_3_0_dispc_features;
> +       } else {
> +               dispc.feat = &omap4_dispc_features;
> +       }
> +
> +       return 0;
> +}
> +




-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-14 12:15         ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-14 12:15 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev

> +static const struct __initdata dispc_features omap2_dispc_features = {
> +       .hp_max                 =       256,
> +       .vp_max                 =       255,
> +       .sw_max                 =       64,
> +       .sw_start               =       5,
> +       .fp_start               =       15,
> +       .bp_start               =       27,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_24xx,
> +       .calc_core_clk          =       calc_core_clk_24xx,
> +};
> +
> +static const struct __initdata dispc_features omap3_2_1_dispc_features = {
> +       .hp_max                 =       256,
> +       .vp_max                 =       255,
> +       .sw_max                 =       64,
> +       .sw_start               =       5,
> +       .fp_start               =       15,
> +       .bp_start               =       27,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> +       .calc_core_clk          =       calc_core_clk_34xx,
> +};
> +
> +static const struct __initdata dispc_features omap3_3_0_dispc_features = {
> +       .hp_max                 =       4096,
> +       .vp_max                 =       4095,
> +       .sw_max                 =       256,
> +       .sw_start               =       7,
> +       .fp_start               =       19,
> +       .bp_start               =       31,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> +       .calc_core_clk          =       calc_core_clk_34xx,
> +};
> +
> +static const struct __initdata dispc_features omap4_dispc_features = {
> +       .hp_max                 =       4096,
> +       .vp_max                 =       4095,
> +       .sw_max                 =       256,
> +       .sw_start               =       7,
> +       .fp_start               =       19,
> +       .bp_start               =       31,
> +       .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
> +       .calc_core_clk          =       calc_core_clk_44xx,
> +};
> +

Here the dispc_features not only mention the omap name but also the
revision like omap3_3_0_dispc_features which initializes data for
OMAP3430_REV_ES3_0 and higher. May be omap34xx_rev3_0_dispc_features
is a better name for this. For others omap44xx_dispc_features kind of
name should be ok without revision number being mentioned. What d you
say?

> +static int __init dispc_init_features(struct device *dev)
> +{
> +       dispc.feat = devm_kzalloc(dev, sizeof(*dispc.feat), GFP_KERNEL);
> +       if (!dispc.feat) {
> +               dev_err(dev, "Failed to allocate DISPC Features\n");
> +               return -ENOMEM;
> +       }
> +
> +       if (cpu_is_omap24xx()) {
> +               dispc.feat = &omap2_dispc_features;
> +       } else if (cpu_is_omap34xx()) {
> +               if (omap_rev() < OMAP3430_REV_ES3_0)
> +                       dispc.feat = &omap3_2_1_dispc_features;
> +               else
> +                       dispc.feat = &omap3_3_0_dispc_features;
> +       } else {
> +               dispc.feat = &omap4_dispc_features;
> +       }
> +
> +       return 0;
> +}
> +




-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-14 12:15         ` Mahapatra, Chandrabhanu
@ 2012-08-14 12:16           ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 12:16 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2590 bytes --]

On Tue, 2012-08-14 at 17:33 +0530, Mahapatra, Chandrabhanu wrote:
> > +static const struct __initdata dispc_features omap2_dispc_features = {
> > +       .hp_max                 =       256,
> > +       .vp_max                 =       255,
> > +       .sw_max                 =       64,
> > +       .sw_start               =       5,
> > +       .fp_start               =       15,
> > +       .bp_start               =       27,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_24xx,
> > +       .calc_core_clk          =       calc_core_clk_24xx,
> > +};
> > +
> > +static const struct __initdata dispc_features omap3_2_1_dispc_features = {
> > +       .hp_max                 =       256,
> > +       .vp_max                 =       255,
> > +       .sw_max                 =       64,
> > +       .sw_start               =       5,
> > +       .fp_start               =       15,
> > +       .bp_start               =       27,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> > +       .calc_core_clk          =       calc_core_clk_34xx,
> > +};
> > +
> > +static const struct __initdata dispc_features omap3_3_0_dispc_features = {
> > +       .hp_max                 =       4096,
> > +       .vp_max                 =       4095,
> > +       .sw_max                 =       256,
> > +       .sw_start               =       7,
> > +       .fp_start               =       19,
> > +       .bp_start               =       31,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> > +       .calc_core_clk          =       calc_core_clk_34xx,
> > +};
> > +
> > +static const struct __initdata dispc_features omap4_dispc_features = {
> > +       .hp_max                 =       4096,
> > +       .vp_max                 =       4095,
> > +       .sw_max                 =       256,
> > +       .sw_start               =       7,
> > +       .fp_start               =       19,
> > +       .bp_start               =       31,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
> > +       .calc_core_clk          =       calc_core_clk_44xx,
> > +};
> > +
> 
> Here the dispc_features not only mention the omap name but also the
> revision like omap3_3_0_dispc_features which initializes data for
> OMAP3430_REV_ES3_0 and higher. May be omap34xx_rev3_0_dispc_features
> is a better name for this. For others omap44xx_dispc_features kind of
> name should be ok without revision number being mentioned. What d you
> say?

Sounds ok to me.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-14 12:16           ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 12:16 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2590 bytes --]

On Tue, 2012-08-14 at 17:33 +0530, Mahapatra, Chandrabhanu wrote:
> > +static const struct __initdata dispc_features omap2_dispc_features = {
> > +       .hp_max                 =       256,
> > +       .vp_max                 =       255,
> > +       .sw_max                 =       64,
> > +       .sw_start               =       5,
> > +       .fp_start               =       15,
> > +       .bp_start               =       27,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_24xx,
> > +       .calc_core_clk          =       calc_core_clk_24xx,
> > +};
> > +
> > +static const struct __initdata dispc_features omap3_2_1_dispc_features = {
> > +       .hp_max                 =       256,
> > +       .vp_max                 =       255,
> > +       .sw_max                 =       64,
> > +       .sw_start               =       5,
> > +       .fp_start               =       15,
> > +       .bp_start               =       27,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> > +       .calc_core_clk          =       calc_core_clk_34xx,
> > +};
> > +
> > +static const struct __initdata dispc_features omap3_3_0_dispc_features = {
> > +       .hp_max                 =       4096,
> > +       .vp_max                 =       4095,
> > +       .sw_max                 =       256,
> > +       .sw_start               =       7,
> > +       .fp_start               =       19,
> > +       .bp_start               =       31,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
> > +       .calc_core_clk          =       calc_core_clk_34xx,
> > +};
> > +
> > +static const struct __initdata dispc_features omap4_dispc_features = {
> > +       .hp_max                 =       4096,
> > +       .vp_max                 =       4095,
> > +       .sw_max                 =       256,
> > +       .sw_start               =       7,
> > +       .fp_start               =       19,
> > +       .bp_start               =       31,
> > +       .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
> > +       .calc_core_clk          =       calc_core_clk_44xx,
> > +};
> > +
> 
> Here the dispc_features not only mention the omap name but also the
> revision like omap3_3_0_dispc_features which initializes data for
> OMAP3430_REV_ES3_0 and higher. May be omap34xx_rev3_0_dispc_features
> is a better name for this. For others omap44xx_dispc_features kind of
> name should be ok without revision number being mentioned. What d you
> say?

Sounds ok to me.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-14  9:48         ` Tomi Valkeinen
@ 2012-08-14 12:42           ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-14 12:30 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Tue, Aug 14, 2012 at 3:18 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-13 at 17:29 +0530, Chandrabhanu Mahapatra wrote:
>> 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.
>
> It'd be good to have some version information here. Even just [PATCH v3
> 3/6] in the subject is good, but of course the best is if there's a
> short change log
>

Is it ok to have short change log in the individual patch description
itself. I normally prefer the cover letter for this.

>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
>>  1 file changed, 74 insertions(+), 41 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 7b1c6ac..6ab236e 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -31,6 +31,7 @@
>>  #include <linux/clk.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/dma-mapping.h>
>
> Hmm, what is this for?
>

I should have included "include/linux/gfp.h" instead. It defines GFP_KERNEL.

>>  #include <video/omapdss.h>
>>
>> @@ -65,6 +66,13 @@ struct dss_reg {
>>  static int dss_runtime_get(void);
>>  static void dss_runtime_put(void);
>>
>> +struct dss_features {
>> +     u16 fck_div_max;
>> +     int factor;
>> +     char *clk_name;
>> +     bool (*check_cinfo_fck) (void);
>> +};
>
> Is the check_cinfo_fck a leftover from previous versions?
>

Sorry, to have skipped that.

> I think "factor" name is too vague. If I remember right, it's some kind
> of implicit multiplier for the dss fck. So "dss_fck_multiplier"? You
> could check the clock trees to verify what the multiplier exactly was,
> and see if you can come up with a better name =).
>

dss_fck_multiplier sounds good to me. DSS clocks trees do not seem to
mention anything about this multiplier. I found clock "dpll4_mx4_clk"
in omap3 trm but nothing called "dpll_per_m5x2_clk" in omap4 trm. Any
references please you know about?

>> +
>>  static struct {
>>       struct platform_device *pdev;
>>       void __iomem    *base;
>> @@ -83,6 +91,8 @@ static struct {
>>
>>       bool            ctx_valid;
>>       u32             ctx[DSS_SZ_REGS / sizeof(u32)];
>> +
>> +     const struct dss_features *feat;
>>  } dss;
>>
>>  static const char * const dss_generic_clk_source_names[] = {
>> @@ -91,6 +101,30 @@ static const char * const dss_generic_clk_source_names[] = {
>>       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCK",
>>  };
>>
>> +static const struct __initdata dss_features omap2_dss_features = {
>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .clk_name               =       NULL,
>> +};
>
> include/linux/init.h says says __initdata should be used like:
>
> static int init_variable __initdata = 0;
>
> And there actually seems to be __initconst also, which I think is the
> correct one to use here. Didn't know about that =):
>
> static const char linux_logo[] __initconst = { 0x32, 0x36, ... };

Thanks for mentioning.

>
>> +static const struct __initdata dss_features omap34_dss_features = {
>
> Perhaps the names could be more consistent. "omap34" doesn't sound like
> any omap we have ;). So maybe just omap2xxx, omap34xx, etc, the same way
> we have in the cpu_is calls.
>

ok.

>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .clk_name               =       "dpll4_m4_ck",
>> +};
>> +
>> +static const struct __initdata dss_features omap36_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .clk_name               =       "dpll4_m4_ck",
>> +};
>> +
>> +static const struct __initdata dss_features omap4_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .clk_name               =       "dpll_per_m5x2_ck",
>> +};
>> +
>>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>>  {
>>       __raw_writel(val, dss.base + idx.idx);
>> @@ -236,7 +270,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>>       return dss_generic_clk_source_names[clk_src];
>>  }
>>
>> -
>>  void dss_dump_clocks(struct seq_file *s)
>>  {
>>       unsigned long dpll4_ck_rate;
>> @@ -259,18 +292,10 @@ void dss_dump_clocks(struct seq_file *s)
>>
>>               seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>>
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> -             else
>> -                     seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> +             seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
>> +                             fclk_name, fclk_real_name, dpll4_ck_rate,
>> +                             dpll4_ck_rate / dpll4_m4_ck_rate,
>> +                             dss.feat->factor, fclk_rate);
>>       } else {
>>               seq_printf(s, "%s (%s) = %lu\n",
>>                               fclk_name, fclk_real_name,
>> @@ -470,7 +495,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>
>>       unsigned long fck, max_dss_fck;
>>
>> -     u16 fck_div, fck_div_max = 16;
>> +     u16 fck_div;
>>
>>       int match = 0;
>>       int min_fck_per_pck;
>> @@ -480,9 +505,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>       max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>>
>>       fck = clk_get_rate(dss.dss_clk);
>> -     if (req_pck == dss.cache_req_pck &&
>> -                     ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
>> -                      dss.cache_dss_cinfo.fck == fck)) {
>> +     if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
>> +             dss.cache_dss_cinfo.fck == fck) {
>>               DSSDBG("dispc clock info found from cache.\n");
>>               *dss_cinfo = dss.cache_dss_cinfo;
>>               *dispc_cinfo = dss.cache_dispc_cinfo;
>> @@ -519,16 +543,10 @@ retry:
>>
>>               goto found;
>>       } else {
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     fck_div_max = 32;
>> -
>> -             for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
>> +             for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>>                       struct dispc_clock_info cur_dispc;
>>
>> -                     if (fck_div_max == 32)
>> -                             fck = prate / fck_div;
>> -                     else
>> -                             fck = prate / fck_div * 2;
>> +                     fck = prate / fck_div * dss.feat->factor;
>>
>>                       if (fck > max_dss_fck)
>>                               continue;
>> @@ -633,22 +651,11 @@ static int dss_get_clocks(void)
>>
>>       dss.dss_clk = clk;
>>
>> -     if (cpu_is_omap34xx()) {
>> -             clk = clk_get(NULL, "dpll4_m4_ck");
>> -             if (IS_ERR(clk)) {
>> -                     DSSERR("Failed to get dpll4_m4_ck\n");
>> -                     r = PTR_ERR(clk);
>> -                     goto err;
>> -             }
>> -     } else if (cpu_is_omap44xx()) {
>> -             clk = clk_get(NULL, "dpll_per_m5x2_ck");
>> -             if (IS_ERR(clk)) {
>> -                     DSSERR("Failed to get dpll_per_m5x2_ck\n");
>> -                     r = PTR_ERR(clk);
>> -                     goto err;
>> -             }
>> -     } else { /* omap24xx */
>> -             clk = NULL;
>> +     clk = clk_get(NULL, dss.feat->clk_name);
>> +     if (IS_ERR(clk)) {
>> +             DSSERR("Failed to get %s\n", dss.feat->clk_name);
>> +             r = PTR_ERR(clk);
>> +             goto err;
>>       }
>>
>>       dss.dpll4_m4_ck = clk;
>> @@ -704,6 +711,26 @@ void dss_debug_dump_clocks(struct seq_file *s)
>>  }
>>  #endif
>>
>> +static int __init dss_init_features(struct device *dev)
>> +{
>> +     dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
>> +     if (!dss.feat) {
>> +             dev_err(dev, "Failed to allocate local DSS Features\n");
>> +             return -ENOMEM;
>> +     }
>> +
>> +     if (cpu_is_omap24xx())
>> +             dss.feat = &omap2_dss_features;
>> +     else if (cpu_is_omap34xx())
>> +             dss.feat = &omap34_dss_features;
>> +     else if (cpu_is_omap3630())
>> +             dss.feat = &omap36_dss_features;
>> +     else
>> +             dss.feat = &omap4_dss_features;
>
> Check for omap4 also, and if the cpu is none of the above, return error.
>

I was wondering what error value to return. I was considering EINVAL
(error in value) and ENODEV (no such device). But nothing seems to fit
this case.

>> +
>> +     return 0;
>> +}
>> +
>>  /* DSS HW IP initialisation */
>>  static int __init omap_dsshw_probe(struct platform_device *pdev)
>>  {
>> @@ -750,6 +777,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
>>       dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
>>       dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
>>
>> +     r = dss_init_features(&dss.pdev->dev);
>> +     if (r)
>> +             return r;
>> +
>>       rev = dss_read_reg(DSS_REVISION);
>>       printk(KERN_INFO "OMAP DSS rev %d.%d\n",
>>                       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
>> @@ -772,6 +803,8 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
>>
>>       dss_put_clocks();
>>
>> +     devm_kfree(&dss.pdev->dev, (void *)dss.feat);
>
> You don't need to free the memory allocated with devm_kzalloc. The
> framework will free it automatically on unload (that's the idea of
> devm_* functions).
>

Ok.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-14 12:42           ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-14 12:42 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Tue, Aug 14, 2012 at 3:18 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-13 at 17:29 +0530, Chandrabhanu Mahapatra wrote:
>> 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.
>
> It'd be good to have some version information here. Even just [PATCH v3
> 3/6] in the subject is good, but of course the best is if there's a
> short change log
>

Is it ok to have short change log in the individual patch description
itself. I normally prefer the cover letter for this.

>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
>>  1 file changed, 74 insertions(+), 41 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 7b1c6ac..6ab236e 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -31,6 +31,7 @@
>>  #include <linux/clk.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/dma-mapping.h>
>
> Hmm, what is this for?
>

I should have included "include/linux/gfp.h" instead. It defines GFP_KERNEL.

>>  #include <video/omapdss.h>
>>
>> @@ -65,6 +66,13 @@ struct dss_reg {
>>  static int dss_runtime_get(void);
>>  static void dss_runtime_put(void);
>>
>> +struct dss_features {
>> +     u16 fck_div_max;
>> +     int factor;
>> +     char *clk_name;
>> +     bool (*check_cinfo_fck) (void);
>> +};
>
> Is the check_cinfo_fck a leftover from previous versions?
>

Sorry, to have skipped that.

> I think "factor" name is too vague. If I remember right, it's some kind
> of implicit multiplier for the dss fck. So "dss_fck_multiplier"? You
> could check the clock trees to verify what the multiplier exactly was,
> and see if you can come up with a better name =).
>

dss_fck_multiplier sounds good to me. DSS clocks trees do not seem to
mention anything about this multiplier. I found clock "dpll4_mx4_clk"
in omap3 trm but nothing called "dpll_per_m5x2_clk" in omap4 trm. Any
references please you know about?

>> +
>>  static struct {
>>       struct platform_device *pdev;
>>       void __iomem    *base;
>> @@ -83,6 +91,8 @@ static struct {
>>
>>       bool            ctx_valid;
>>       u32             ctx[DSS_SZ_REGS / sizeof(u32)];
>> +
>> +     const struct dss_features *feat;
>>  } dss;
>>
>>  static const char * const dss_generic_clk_source_names[] = {
>> @@ -91,6 +101,30 @@ static const char * const dss_generic_clk_source_names[] = {
>>       [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCK",
>>  };
>>
>> +static const struct __initdata dss_features omap2_dss_features = {
>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .clk_name               =       NULL,
>> +};
>
> include/linux/init.h says says __initdata should be used like:
>
> static int init_variable __initdata = 0;
>
> And there actually seems to be __initconst also, which I think is the
> correct one to use here. Didn't know about that =):
>
> static const char linux_logo[] __initconst = { 0x32, 0x36, ... };

Thanks for mentioning.

>
>> +static const struct __initdata dss_features omap34_dss_features = {
>
> Perhaps the names could be more consistent. "omap34" doesn't sound like
> any omap we have ;). So maybe just omap2xxx, omap34xx, etc, the same way
> we have in the cpu_is calls.
>

ok.

>> +     .fck_div_max            =       16,
>> +     .factor                 =       2,
>> +     .clk_name               =       "dpll4_m4_ck",
>> +};
>> +
>> +static const struct __initdata dss_features omap36_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .clk_name               =       "dpll4_m4_ck",
>> +};
>> +
>> +static const struct __initdata dss_features omap4_dss_features = {
>> +     .fck_div_max            =       32,
>> +     .factor                 =       1,
>> +     .clk_name               =       "dpll_per_m5x2_ck",
>> +};
>> +
>>  static inline void dss_write_reg(const struct dss_reg idx, u32 val)
>>  {
>>       __raw_writel(val, dss.base + idx.idx);
>> @@ -236,7 +270,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
>>       return dss_generic_clk_source_names[clk_src];
>>  }
>>
>> -
>>  void dss_dump_clocks(struct seq_file *s)
>>  {
>>       unsigned long dpll4_ck_rate;
>> @@ -259,18 +292,10 @@ void dss_dump_clocks(struct seq_file *s)
>>
>>               seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
>>
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> -             else
>> -                     seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
>> -                                     fclk_name, fclk_real_name,
>> -                                     dpll4_ck_rate,
>> -                                     dpll4_ck_rate / dpll4_m4_ck_rate,
>> -                                     fclk_rate);
>> +             seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
>> +                             fclk_name, fclk_real_name, dpll4_ck_rate,
>> +                             dpll4_ck_rate / dpll4_m4_ck_rate,
>> +                             dss.feat->factor, fclk_rate);
>>       } else {
>>               seq_printf(s, "%s (%s) = %lu\n",
>>                               fclk_name, fclk_real_name,
>> @@ -470,7 +495,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>
>>       unsigned long fck, max_dss_fck;
>>
>> -     u16 fck_div, fck_div_max = 16;
>> +     u16 fck_div;
>>
>>       int match = 0;
>>       int min_fck_per_pck;
>> @@ -480,9 +505,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
>>       max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
>>
>>       fck = clk_get_rate(dss.dss_clk);
>> -     if (req_pck = dss.cache_req_pck &&
>> -                     ((cpu_is_omap34xx() && prate = dss.cache_prate) ||
>> -                      dss.cache_dss_cinfo.fck = fck)) {
>> +     if (req_pck = dss.cache_req_pck && prate = dss.cache_prate &&
>> +             dss.cache_dss_cinfo.fck = fck) {
>>               DSSDBG("dispc clock info found from cache.\n");
>>               *dss_cinfo = dss.cache_dss_cinfo;
>>               *dispc_cinfo = dss.cache_dispc_cinfo;
>> @@ -519,16 +543,10 @@ retry:
>>
>>               goto found;
>>       } else {
>> -             if (cpu_is_omap3630() || cpu_is_omap44xx())
>> -                     fck_div_max = 32;
>> -
>> -             for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
>> +             for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
>>                       struct dispc_clock_info cur_dispc;
>>
>> -                     if (fck_div_max = 32)
>> -                             fck = prate / fck_div;
>> -                     else
>> -                             fck = prate / fck_div * 2;
>> +                     fck = prate / fck_div * dss.feat->factor;
>>
>>                       if (fck > max_dss_fck)
>>                               continue;
>> @@ -633,22 +651,11 @@ static int dss_get_clocks(void)
>>
>>       dss.dss_clk = clk;
>>
>> -     if (cpu_is_omap34xx()) {
>> -             clk = clk_get(NULL, "dpll4_m4_ck");
>> -             if (IS_ERR(clk)) {
>> -                     DSSERR("Failed to get dpll4_m4_ck\n");
>> -                     r = PTR_ERR(clk);
>> -                     goto err;
>> -             }
>> -     } else if (cpu_is_omap44xx()) {
>> -             clk = clk_get(NULL, "dpll_per_m5x2_ck");
>> -             if (IS_ERR(clk)) {
>> -                     DSSERR("Failed to get dpll_per_m5x2_ck\n");
>> -                     r = PTR_ERR(clk);
>> -                     goto err;
>> -             }
>> -     } else { /* omap24xx */
>> -             clk = NULL;
>> +     clk = clk_get(NULL, dss.feat->clk_name);
>> +     if (IS_ERR(clk)) {
>> +             DSSERR("Failed to get %s\n", dss.feat->clk_name);
>> +             r = PTR_ERR(clk);
>> +             goto err;
>>       }
>>
>>       dss.dpll4_m4_ck = clk;
>> @@ -704,6 +711,26 @@ void dss_debug_dump_clocks(struct seq_file *s)
>>  }
>>  #endif
>>
>> +static int __init dss_init_features(struct device *dev)
>> +{
>> +     dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
>> +     if (!dss.feat) {
>> +             dev_err(dev, "Failed to allocate local DSS Features\n");
>> +             return -ENOMEM;
>> +     }
>> +
>> +     if (cpu_is_omap24xx())
>> +             dss.feat = &omap2_dss_features;
>> +     else if (cpu_is_omap34xx())
>> +             dss.feat = &omap34_dss_features;
>> +     else if (cpu_is_omap3630())
>> +             dss.feat = &omap36_dss_features;
>> +     else
>> +             dss.feat = &omap4_dss_features;
>
> Check for omap4 also, and if the cpu is none of the above, return error.
>

I was wondering what error value to return. I was considering EINVAL
(error in value) and ENODEV (no such device). But nothing seems to fit
this case.

>> +
>> +     return 0;
>> +}
>> +
>>  /* DSS HW IP initialisation */
>>  static int __init omap_dsshw_probe(struct platform_device *pdev)
>>  {
>> @@ -750,6 +777,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
>>       dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
>>       dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
>>
>> +     r = dss_init_features(&dss.pdev->dev);
>> +     if (r)
>> +             return r;
>> +
>>       rev = dss_read_reg(DSS_REVISION);
>>       printk(KERN_INFO "OMAP DSS rev %d.%d\n",
>>                       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
>> @@ -772,6 +803,8 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
>>
>>       dss_put_clocks();
>>
>> +     devm_kfree(&dss.pdev->dev, (void *)dss.feat);
>
> You don't need to free the memory allocated with devm_kzalloc. The
> framework will free it automatically on unload (that's the idea of
> devm_* functions).
>

Ok.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-14 12:42           ` Mahapatra, Chandrabhanu
@ 2012-08-14 14:34             ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 14:34 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 4096 bytes --]

On Tue, 2012-08-14 at 18:00 +0530, Mahapatra, Chandrabhanu wrote:
> On Tue, Aug 14, 2012 at 3:18 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > On Mon, 2012-08-13 at 17:29 +0530, Chandrabhanu Mahapatra wrote:
> >> 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.
> >
> > It'd be good to have some version information here. Even just [PATCH v3
> > 3/6] in the subject is good, but of course the best is if there's a
> > short change log
> >
> 
> Is it ok to have short change log in the individual patch description
> itself. I normally prefer the cover letter for this.

No, the patch description is added to git repository, and shouldn't
contain that kind of "extra" information. But you can add the version
information to the posted patch.

The diff stats below, after the "---" line, are discarded by git when
applying the patch. So I think you can just insert any text below ---
(but before the actual diffs) and they do not appear in the final git
commit.

I've not actually used that myself, and I can't find notes about it in
the documentation, so I'm not sure if there are any restrictions about
it. I've seen it used, though.

> >> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> >> ---
> >>  drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
> >>  1 file changed, 74 insertions(+), 41 deletions(-)
> >>
> >> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> >> index 7b1c6ac..6ab236e 100644
> >> --- a/drivers/video/omap2/dss/dss.c
> >> +++ b/drivers/video/omap2/dss/dss.c
> >> @@ -31,6 +31,7 @@
> >>  #include <linux/clk.h>
> >>  #include <linux/platform_device.h>
> >>  #include <linux/pm_runtime.h>
> >> +#include <linux/dma-mapping.h>
> >
> > Hmm, what is this for?
> >
> 
> I should have included "include/linux/gfp.h" instead. It defines GFP_KERNEL.
> 
> >>  #include <video/omapdss.h>
> >>
> >> @@ -65,6 +66,13 @@ struct dss_reg {
> >>  static int dss_runtime_get(void);
> >>  static void dss_runtime_put(void);
> >>
> >> +struct dss_features {
> >> +     u16 fck_div_max;
> >> +     int factor;
> >> +     char *clk_name;
> >> +     bool (*check_cinfo_fck) (void);
> >> +};
> >
> > Is the check_cinfo_fck a leftover from previous versions?
> >
> 
> Sorry, to have skipped that.
> 
> > I think "factor" name is too vague. If I remember right, it's some kind
> > of implicit multiplier for the dss fck. So "dss_fck_multiplier"? You
> > could check the clock trees to verify what the multiplier exactly was,
> > and see if you can come up with a better name =).
> >
> 
> dss_fck_multiplier sounds good to me. DSS clocks trees do not seem to

Yes, it's not really DSS thing, but PRCM. If things were perfect, DSS
wouldn't even need to know about the clock.

> mention anything about this multiplier. I found clock "dpll4_mx4_clk"
> in omap3 trm but nothing called "dpll_per_m5x2_clk" in omap4 trm. Any
> references please you know about?

Hmm, I think that's the linux's name for it. TRM seems to call it
CLKOUTX2_M5 (in the power, reset and clock management section).

> >> +     if (cpu_is_omap24xx())
> >> +             dss.feat = &omap2_dss_features;
> >> +     else if (cpu_is_omap34xx())
> >> +             dss.feat = &omap34_dss_features;
> >> +     else if (cpu_is_omap3630())
> >> +             dss.feat = &omap36_dss_features;
> >> +     else
> >> +             dss.feat = &omap4_dss_features;
> >
> > Check for omap4 also, and if the cpu is none of the above, return error.
> >
> 
> I was wondering what error value to return. I was considering EINVAL
> (error in value) and ENODEV (no such device). But nothing seems to fit
> this case.

ENODEV sounds fine to me. I think EINVAL should be used when some given
parameter was wrong.


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-14 14:34             ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 14:34 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 4096 bytes --]

On Tue, 2012-08-14 at 18:00 +0530, Mahapatra, Chandrabhanu wrote:
> On Tue, Aug 14, 2012 at 3:18 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > On Mon, 2012-08-13 at 17:29 +0530, Chandrabhanu Mahapatra wrote:
> >> 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.
> >
> > It'd be good to have some version information here. Even just [PATCH v3
> > 3/6] in the subject is good, but of course the best is if there's a
> > short change log
> >
> 
> Is it ok to have short change log in the individual patch description
> itself. I normally prefer the cover letter for this.

No, the patch description is added to git repository, and shouldn't
contain that kind of "extra" information. But you can add the version
information to the posted patch.

The diff stats below, after the "---" line, are discarded by git when
applying the patch. So I think you can just insert any text below ---
(but before the actual diffs) and they do not appear in the final git
commit.

I've not actually used that myself, and I can't find notes about it in
the documentation, so I'm not sure if there are any restrictions about
it. I've seen it used, though.

> >> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> >> ---
> >>  drivers/video/omap2/dss/dss.c |  115 ++++++++++++++++++++++++++---------------
> >>  1 file changed, 74 insertions(+), 41 deletions(-)
> >>
> >> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> >> index 7b1c6ac..6ab236e 100644
> >> --- a/drivers/video/omap2/dss/dss.c
> >> +++ b/drivers/video/omap2/dss/dss.c
> >> @@ -31,6 +31,7 @@
> >>  #include <linux/clk.h>
> >>  #include <linux/platform_device.h>
> >>  #include <linux/pm_runtime.h>
> >> +#include <linux/dma-mapping.h>
> >
> > Hmm, what is this for?
> >
> 
> I should have included "include/linux/gfp.h" instead. It defines GFP_KERNEL.
> 
> >>  #include <video/omapdss.h>
> >>
> >> @@ -65,6 +66,13 @@ struct dss_reg {
> >>  static int dss_runtime_get(void);
> >>  static void dss_runtime_put(void);
> >>
> >> +struct dss_features {
> >> +     u16 fck_div_max;
> >> +     int factor;
> >> +     char *clk_name;
> >> +     bool (*check_cinfo_fck) (void);
> >> +};
> >
> > Is the check_cinfo_fck a leftover from previous versions?
> >
> 
> Sorry, to have skipped that.
> 
> > I think "factor" name is too vague. If I remember right, it's some kind
> > of implicit multiplier for the dss fck. So "dss_fck_multiplier"? You
> > could check the clock trees to verify what the multiplier exactly was,
> > and see if you can come up with a better name =).
> >
> 
> dss_fck_multiplier sounds good to me. DSS clocks trees do not seem to

Yes, it's not really DSS thing, but PRCM. If things were perfect, DSS
wouldn't even need to know about the clock.

> mention anything about this multiplier. I found clock "dpll4_mx4_clk"
> in omap3 trm but nothing called "dpll_per_m5x2_clk" in omap4 trm. Any
> references please you know about?

Hmm, I think that's the linux's name for it. TRM seems to call it
CLKOUTX2_M5 (in the power, reset and clock management section).

> >> +     if (cpu_is_omap24xx())
> >> +             dss.feat = &omap2_dss_features;
> >> +     else if (cpu_is_omap34xx())
> >> +             dss.feat = &omap34_dss_features;
> >> +     else if (cpu_is_omap3630())
> >> +             dss.feat = &omap36_dss_features;
> >> +     else
> >> +             dss.feat = &omap4_dss_features;
> >
> > Check for omap4 also, and if the cpu is none of the above, return error.
> >
> 
> I was wondering what error value to return. I was considering EINVAL
> (error in value) and ENODEV (no such device). But nothing seems to fit
> this case.

ENODEV sounds fine to me. I think EINVAL should be used when some given
parameter was wrong.


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V4 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-13 12:10       ` Chandrabhanu Mahapatra
@ 2012-08-16 11:30         ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-16 11:18 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  428 +++++++++++++++++++++++++--------------
 1 file changed, 273 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..0415845 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int hp_max;
+	int vp_max;
+	int sw_max;
+	int sw_start;
+	int fp_start;
+	int bp_start;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
 	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth =
+				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth =
-				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width == out_width && height == out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,74 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct dispc_features omap24xx_dispc_features __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_features __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_features __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap44xx_dispc_features __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	dispc.feat = devm_kzalloc(dev, sizeof(*dispc.feat), GFP_KERNEL);
+	if (!dispc.feat) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		dispc.feat = &omap24xx_dispc_features;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			dispc.feat = &omap34xx_rev1_0_dispc_features;
+		else
+			dispc.feat = &omap34xx_rev3_0_dispc_features;
+	} else if (cpu_is_omap44xx()) {
+		dispc.feat = &omap44xx_dispc_features;
+	} else {
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3725,6 +3839,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
-- 
1.7.10

changes since V1
	V2 : moved dispc_ops structure definitions from dss_features.c to dispc.c
	     renamed dispc_ops to dispc_features
	V3 : moved dispc_features definitions close to dispc_init_features thereby
		eliminating various functions declarations from top of dispc.c
	     used __initdata before dispc_features definitions and __init before
		dispc_init_features()
	     initialized dispc.feat with devm_kzalloc
	     removed definitions of _dispc_lcd_timings_ok_24xx,
		_dispc_lcd_timings_ok_44xx, _dispc_mgr_set_lcd_timings_hv_24xx and
		_dispc_mgr_set_lcd_timings_hv_44xx replacing them with appropiate
		variables
	V4 : replaced __initdata with __initconst as per guidelines in
		include/linux/init.h
	     renamed various dispc_features structures to give consistent naming
	     removed dispc.feat deinitialization code from omap_dispchw_remove()
	     added a check for omap4 in dispc_init_features()    
	     

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-13 12:11       ` Chandrabhanu Mahapatra
@ 2012-08-16 11:30         ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-16 11:18 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  114 ++++++++++++++++++++++++++---------------
 1 file changed, 73 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..a9cb84b 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/gfp.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,12 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u16 fck_div_max;
+	int dss_fck_multiplier;
+	char *clk_name;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +90,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +100,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap24xx_dss_features __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct dss_features omap34xx_dss_features __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap3630_dss_features __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap44xx_dss_features __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__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)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +291,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->dss_fck_multiplier, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +494,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +504,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck == dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck == fck)) {
+	if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
+		dss.cache_dss_cinfo.fck == fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +542,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max == 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->dss_fck_multiplier;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -633,22 +650,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -704,6 +710,28 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
+	if (!dss.feat) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		dss.feat = &omap24xx_dss_features;
+	else if (cpu_is_omap34xx())
+		dss.feat = &omap34xx_dss_features;
+	else if (cpu_is_omap3630())
+		dss.feat = &omap3630_dss_features;
+	else if (cpu_is_omap44xx())
+		dss.feat = &omap44xx_dss_features;
+	else
+		return -ENODEV;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -750,6 +778,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
-- 
1.7.10

changes since V1
	V2 : moved dss_ops structure definitions from dss_features.c to dss.c
	     renamed dss_ops to dss_features
	     removed dss_get_clk_24xx(), dss_get_clk_34xx(), dss_get_clk_44xx,
		set_dump_clk_str_24_34() and set_dump_clk_str() replacing them
		with appropiate variables in dss_features structure 
	V3 : used __initdata before dss_features definitions and __init before
		dss_init_features()
	     initialized dss.feat with devm_kzalloc
	     removed definitions of check_dss_cinfo_fck(),
		check_dss_cinfo_fck_34xx(), dss_get_clk_24xx(), dss_get_clk_34xx()
		and dss_get_clk_44xx() replacing them with appropiate variables
	V4 : replaced __initdata with __initconst as per guidelines in
		include/linux/init.h
	     renamed various dss_features structures to give consistent naming
	     removed dss.feat deinitialization code from omap_dispchw_remove()
	     replaced #include <linux/dma-mapping.h> with <linux/gfx.h>
	     renamed factor variable of dss_features structure with
		dss_fck_multiplier
	     added a check for omap4 in dss_init_features()
	     

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V4 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-16 11:30         ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-16 11:30 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  428 +++++++++++++++++++++++++--------------
 1 file changed, 273 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..0415845 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int hp_max;
+	int vp_max;
+	int sw_max;
+	int sw_start;
+	int fp_start;
+	int bp_start;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
 	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth +				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth -				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width = out_width && height = out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,74 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct dispc_features omap24xx_dispc_features __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_features __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_features __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap44xx_dispc_features __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	dispc.feat = devm_kzalloc(dev, sizeof(*dispc.feat), GFP_KERNEL);
+	if (!dispc.feat) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		dispc.feat = &omap24xx_dispc_features;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			dispc.feat = &omap34xx_rev1_0_dispc_features;
+		else
+			dispc.feat = &omap34xx_rev3_0_dispc_features;
+	} else if (cpu_is_omap44xx()) {
+		dispc.feat = &omap44xx_dispc_features;
+	} else {
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3725,6 +3839,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.dss_clk = clk;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	pm_runtime_enable(&pdev->dev);
 
 	r = dispc_runtime_get();
-- 
1.7.10

changes since V1
	V2 : moved dispc_ops structure definitions from dss_features.c to dispc.c
	     renamed dispc_ops to dispc_features
	V3 : moved dispc_features definitions close to dispc_init_features thereby
		eliminating various functions declarations from top of dispc.c
	     used __initdata before dispc_features definitions and __init before
		dispc_init_features()
	     initialized dispc.feat with devm_kzalloc
	     removed definitions of _dispc_lcd_timings_ok_24xx,
		_dispc_lcd_timings_ok_44xx, _dispc_mgr_set_lcd_timings_hv_24xx and
		_dispc_mgr_set_lcd_timings_hv_44xx replacing them with appropiate
		variables
	V4 : replaced __initdata with __initconst as per guidelines in
		include/linux/init.h
	     renamed various dispc_features structures to give consistent naming
	     removed dispc.feat deinitialization code from omap_dispchw_remove()
	     added a check for omap4 in dispc_init_features()    
	     

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-16 11:30         ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-16 11:30 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  114 ++++++++++++++++++++++++++---------------
 1 file changed, 73 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 7b1c6ac..a9cb84b 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/gfp.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,12 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u16 fck_div_max;
+	int dss_fck_multiplier;
+	char *clk_name;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +90,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +100,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap24xx_dss_features __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct dss_features omap34xx_dss_features __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap3630_dss_features __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap44xx_dss_features __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__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)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +291,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->dss_fck_multiplier, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +494,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +504,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck = dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate = dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck = fck)) {
+	if (req_pck = dss.cache_req_pck && prate = dss.cache_prate &&
+		dss.cache_dss_cinfo.fck = fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +542,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max = 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->dss_fck_multiplier;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -633,22 +650,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -704,6 +710,28 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
+	if (!dss.feat) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		dss.feat = &omap24xx_dss_features;
+	else if (cpu_is_omap34xx())
+		dss.feat = &omap34xx_dss_features;
+	else if (cpu_is_omap3630())
+		dss.feat = &omap3630_dss_features;
+	else if (cpu_is_omap44xx())
+		dss.feat = &omap44xx_dss_features;
+	else
+		return -ENODEV;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -750,6 +778,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	rev = dss_read_reg(DSS_REVISION);
 	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
 			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
-- 
1.7.10

changes since V1
	V2 : moved dss_ops structure definitions from dss_features.c to dss.c
	     renamed dss_ops to dss_features
	     removed dss_get_clk_24xx(), dss_get_clk_34xx(), dss_get_clk_44xx,
		set_dump_clk_str_24_34() and set_dump_clk_str() replacing them
		with appropiate variables in dss_features structure 
	V3 : used __initdata before dss_features definitions and __init before
		dss_init_features()
	     initialized dss.feat with devm_kzalloc
	     removed definitions of check_dss_cinfo_fck(),
		check_dss_cinfo_fck_34xx(), dss_get_clk_24xx(), dss_get_clk_34xx()
		and dss_get_clk_44xx() replacing them with appropiate variables
	V4 : replaced __initdata with __initconst as per guidelines in
		include/linux/init.h
	     renamed various dss_features structures to give consistent naming
	     removed dss.feat deinitialization code from omap_dispchw_remove()
	     replaced #include <linux/dma-mapping.h> with <linux/gfx.h>
	     renamed factor variable of dss_features structure with
		dss_fck_multiplier
	     added a check for omap4 in dss_init_features()
	     

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-16 11:30         ` Chandrabhanu Mahapatra
@ 2012-08-17 13:54           ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-17 13:54 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 5554 bytes --]

On Thu, 2012-08-16 at 16:48 +0530, Chandrabhanu Mahapatra wrote:
> 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>

> +static int __init dss_init_features(struct device *dev)
> +{
> +	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
> +	if (!dss.feat) {
> +		dev_err(dev, "Failed to allocate local DSS Features\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (cpu_is_omap24xx())
> +		dss.feat = &omap24xx_dss_features;
> +	else if (cpu_is_omap34xx())
> +		dss.feat = &omap34xx_dss_features;
> +	else if (cpu_is_omap3630())
> +		dss.feat = &omap3630_dss_features;
> +	else if (cpu_is_omap44xx())
> +		dss.feat = &omap44xx_dss_features;
> +	else
> +		return -ENODEV;
> +
> +	return 0;
> +}

This is not correct (and same problem in dispc). You allocate the feat
struct and assign the pointer to dss.feat, but then overwrite dss.feat
pointer with the pointer to omap24xx_dss_features (which is freed
later). You need to memcpy it.

I also get a crash on omap3 overo board when loading omapdss:

loading nfs/work/linux/drivers/video/omap2/dss/omapdss.ko debug=y def_disp=lcd43
[   20.411224] Unable to handle kernel NULL pointer dereference at virtual address 00000008
[   20.419921] pgd = ce8a8000
[   20.422790] [00000008] *pgd=8e8c5831, *pte=00000000, *ppte=00000000
[   20.429473] Internal error: Oops: 17 [#1] SMP ARM
[   20.434448] Modules linked in: omapdss(+)
[   20.438690] CPU: 0    Tainted: G        W     (3.5.0-rc2-00058-g1c1e55c #93)
[   20.446350] PC is at omap_dsshw_probe+0xa4/0x290 [omapdss]
[   20.452148] LR is at 0x2e39
[   20.455108] pc : [<bf043288>]    lr : [<00002e39>]    psr: 80000013
[   20.455108] sp : ce89ddd0  ip : c0b797e0  fp : 00006133
[   20.467224] r10: 00000028  r9 : c0c5c07c  r8 : bf02eadc
[   20.472717] r7 : 00000000  r6 : c06e9644  r5 : cf0cf808  r4 : bf02f430
[   20.479614] r3 : cf0cf808  r2 : 00000000  r1 : 00000000  r0 : 00000000
[   20.486511] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[   20.494049] Control: 10c5387d  Table: 8e8a8019  DAC: 00000015
[   20.500091] Process insmod (pid: 664, stack limit = 0xce89c2f8)
[   20.506347] Stack: (0xce89ddd0 to 0xce89e000)
[   20.510955] ddc0:                                     cf0cf808 c0c96ed8 c0c96ee8 c02c22e4
[   20.519592] dde0: c02c22cc c02c0f28 22222222 cf0cf808 bf02eadc cf0cf83c 00000000 00000001
[   20.528198] de00: 00000028 c02c113c bf02eadc c02c10a8 00000000 c02bf6c8 cf0192a8 cf0cec10
[   20.536834] de20: bf02eadc c072fab8 cf3e7440 c02c05dc bf0249e0 00000000 cf04ce40 bf02eadc
[   20.545471] de40: c0748880 ce89c000 00000000 00000001 c0c5c07c 00000028 00006133 c02c1670
[   20.554107] de60: 00000000 bf02eac8 c0748880 ce89c000 00000000 00000001 00000028 c02c26e0
[   20.562744] de80: 00000003 00000000 c0748880 bf043124 00000000 c0748880 ce89c000 00000000
[   20.571380] dea0: 00000001 c0008730 bf02f29c 00000001 00000001 bf0430cc c071bcd0 00000000
[   20.580017] dec0: bf02f29c c006823c 00000000 ce827ec0 cf0001c0 00000000 bf02f29c 00000001
[   20.588623] dee0: ce851480 00000001 c0c5c07c 00000028 00006133 c0099d20 bf02f2a8 00007fff
[   20.597259] df00: c0098aa4 c012480c 00000000 c0098890 bf02f3f0 ce89c000 c06d32d8 d08fe09c
[   20.605895] df20: d0a19624 000a7008 d08ce000 001f2ab7 d0a18bd4 d0a18948 d0aba984 00030ed0
[   20.614532] df40: 0003b0e0 00000000 00000000 00000042 00000043 00000026 0000002a 00000014
[   20.623138] df60: 00000000 bf022024 00000043 00000000 00000000 00000000 00000000 c0623b14
[   20.631774] df80: 001f2ab7 001f2ab7 00000004 beb48e7c 00000080 c0013f28 ce89c000 00000000
[   20.640411] dfa0: 00000000 c0013d60 001f2ab7 00000004 b6c49008 001f2ab7 000a7008 beb48e7c
[   20.649047] dfc0: 001f2ab7 00000004 beb48e7c 00000080 000a47f8 00000000 b6f80000 00000000
[   20.657684] dfe0: beb48bb8 beb48ba8 00019dfc b6f10020 60000010 b6c49008 00000000 00000000
[   20.666442] [<bf043288>] (omap_dsshw_probe+0xa4/0x290 [omapdss]) from [<c02c22e4>] (platform_drv_
probe+0x18/0x1c)
[   20.677276] [<c02c22e4>] (platform_drv_probe+0x18/0x1c) from [<c02c0f28>] (driver_probe_device+0x
9c/0x21c)
[   20.687499] [<c02c0f28>] (driver_probe_device+0x9c/0x21c) from [<c02c113c>] (__driver_attach+0x94
/0x98)
[   20.697418] [<c02c113c>] (__driver_attach+0x94/0x98) from [<c02bf6c8>] (bus_for_each_dev+0x50/0x7
c)
[   20.706970] [<c02bf6c8>] (bus_for_each_dev+0x50/0x7c) from [<c02c05dc>] (bus_add_driver+0xa0/0x2a
8)
[   20.716522] [<c02c05dc>] (bus_add_driver+0xa0/0x2a8) from [<c02c1670>] (driver_register+0x78/0x17
4)
[   20.726074] [<c02c1670>] (driver_register+0x78/0x174) from [<c02c26e0>] (platform_driver_probe+0x
18/0x9c)
[   20.736267] [<c02c26e0>] (platform_driver_probe+0x18/0x9c) from [<bf043124>] (omap_dss_init+0x58/
0x118 [omapdss])
[   20.747192] [<bf043124>] (omap_dss_init+0x58/0x118 [omapdss]) from [<c0008730>] (do_one_initcall+
0x34/0x194)
[   20.757568] [<c0008730>] (do_one_initcall+0x34/0x194) from [<c0099d20>] (sys_init_module+0xdc/0x1
cc4)
[   20.767333] [<c0099d20>] (sys_init_module+0xdc/0x1cc4) from [<c0013d60>] (ret_fast_syscall+0x0/0x
3c)
[   20.776947] Code: ea00000d e5941248 e3a00000 e584600c (e5911008) 
[   20.783599] ---[ end trace bcb6e89e4ea810ae ]---



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-17 13:54           ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-17 13:54 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 5554 bytes --]

On Thu, 2012-08-16 at 16:48 +0530, Chandrabhanu Mahapatra wrote:
> 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>

> +static int __init dss_init_features(struct device *dev)
> +{
> +	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
> +	if (!dss.feat) {
> +		dev_err(dev, "Failed to allocate local DSS Features\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (cpu_is_omap24xx())
> +		dss.feat = &omap24xx_dss_features;
> +	else if (cpu_is_omap34xx())
> +		dss.feat = &omap34xx_dss_features;
> +	else if (cpu_is_omap3630())
> +		dss.feat = &omap3630_dss_features;
> +	else if (cpu_is_omap44xx())
> +		dss.feat = &omap44xx_dss_features;
> +	else
> +		return -ENODEV;
> +
> +	return 0;
> +}

This is not correct (and same problem in dispc). You allocate the feat
struct and assign the pointer to dss.feat, but then overwrite dss.feat
pointer with the pointer to omap24xx_dss_features (which is freed
later). You need to memcpy it.

I also get a crash on omap3 overo board when loading omapdss:

loading nfs/work/linux/drivers/video/omap2/dss/omapdss.ko debug=y def_disp=lcd43
[   20.411224] Unable to handle kernel NULL pointer dereference at virtual address 00000008
[   20.419921] pgd = ce8a8000
[   20.422790] [00000008] *pgd=8e8c5831, *pte=00000000, *ppte=00000000
[   20.429473] Internal error: Oops: 17 [#1] SMP ARM
[   20.434448] Modules linked in: omapdss(+)
[   20.438690] CPU: 0    Tainted: G        W     (3.5.0-rc2-00058-g1c1e55c #93)
[   20.446350] PC is at omap_dsshw_probe+0xa4/0x290 [omapdss]
[   20.452148] LR is at 0x2e39
[   20.455108] pc : [<bf043288>]    lr : [<00002e39>]    psr: 80000013
[   20.455108] sp : ce89ddd0  ip : c0b797e0  fp : 00006133
[   20.467224] r10: 00000028  r9 : c0c5c07c  r8 : bf02eadc
[   20.472717] r7 : 00000000  r6 : c06e9644  r5 : cf0cf808  r4 : bf02f430
[   20.479614] r3 : cf0cf808  r2 : 00000000  r1 : 00000000  r0 : 00000000
[   20.486511] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[   20.494049] Control: 10c5387d  Table: 8e8a8019  DAC: 00000015
[   20.500091] Process insmod (pid: 664, stack limit = 0xce89c2f8)
[   20.506347] Stack: (0xce89ddd0 to 0xce89e000)
[   20.510955] ddc0:                                     cf0cf808 c0c96ed8 c0c96ee8 c02c22e4
[   20.519592] dde0: c02c22cc c02c0f28 22222222 cf0cf808 bf02eadc cf0cf83c 00000000 00000001
[   20.528198] de00: 00000028 c02c113c bf02eadc c02c10a8 00000000 c02bf6c8 cf0192a8 cf0cec10
[   20.536834] de20: bf02eadc c072fab8 cf3e7440 c02c05dc bf0249e0 00000000 cf04ce40 bf02eadc
[   20.545471] de40: c0748880 ce89c000 00000000 00000001 c0c5c07c 00000028 00006133 c02c1670
[   20.554107] de60: 00000000 bf02eac8 c0748880 ce89c000 00000000 00000001 00000028 c02c26e0
[   20.562744] de80: 00000003 00000000 c0748880 bf043124 00000000 c0748880 ce89c000 00000000
[   20.571380] dea0: 00000001 c0008730 bf02f29c 00000001 00000001 bf0430cc c071bcd0 00000000
[   20.580017] dec0: bf02f29c c006823c 00000000 ce827ec0 cf0001c0 00000000 bf02f29c 00000001
[   20.588623] dee0: ce851480 00000001 c0c5c07c 00000028 00006133 c0099d20 bf02f2a8 00007fff
[   20.597259] df00: c0098aa4 c012480c 00000000 c0098890 bf02f3f0 ce89c000 c06d32d8 d08fe09c
[   20.605895] df20: d0a19624 000a7008 d08ce000 001f2ab7 d0a18bd4 d0a18948 d0aba984 00030ed0
[   20.614532] df40: 0003b0e0 00000000 00000000 00000042 00000043 00000026 0000002a 00000014
[   20.623138] df60: 00000000 bf022024 00000043 00000000 00000000 00000000 00000000 c0623b14
[   20.631774] df80: 001f2ab7 001f2ab7 00000004 beb48e7c 00000080 c0013f28 ce89c000 00000000
[   20.640411] dfa0: 00000000 c0013d60 001f2ab7 00000004 b6c49008 001f2ab7 000a7008 beb48e7c
[   20.649047] dfc0: 001f2ab7 00000004 beb48e7c 00000080 000a47f8 00000000 b6f80000 00000000
[   20.657684] dfe0: beb48bb8 beb48ba8 00019dfc b6f10020 60000010 b6c49008 00000000 00000000
[   20.666442] [<bf043288>] (omap_dsshw_probe+0xa4/0x290 [omapdss]) from [<c02c22e4>] (platform_drv_
probe+0x18/0x1c)
[   20.677276] [<c02c22e4>] (platform_drv_probe+0x18/0x1c) from [<c02c0f28>] (driver_probe_device+0x
9c/0x21c)
[   20.687499] [<c02c0f28>] (driver_probe_device+0x9c/0x21c) from [<c02c113c>] (__driver_attach+0x94
/0x98)
[   20.697418] [<c02c113c>] (__driver_attach+0x94/0x98) from [<c02bf6c8>] (bus_for_each_dev+0x50/0x7
c)
[   20.706970] [<c02bf6c8>] (bus_for_each_dev+0x50/0x7c) from [<c02c05dc>] (bus_add_driver+0xa0/0x2a
8)
[   20.716522] [<c02c05dc>] (bus_add_driver+0xa0/0x2a8) from [<c02c1670>] (driver_register+0x78/0x17
4)
[   20.726074] [<c02c1670>] (driver_register+0x78/0x174) from [<c02c26e0>] (platform_driver_probe+0x
18/0x9c)
[   20.736267] [<c02c26e0>] (platform_driver_probe+0x18/0x9c) from [<bf043124>] (omap_dss_init+0x58/
0x118 [omapdss])
[   20.747192] [<bf043124>] (omap_dss_init+0x58/0x118 [omapdss]) from [<c0008730>] (do_one_initcall+
0x34/0x194)
[   20.757568] [<c0008730>] (do_one_initcall+0x34/0x194) from [<c0099d20>] (sys_init_module+0xdc/0x1
cc4)
[   20.767333] [<c0099d20>] (sys_init_module+0xdc/0x1cc4) from [<c0013d60>] (ret_fast_syscall+0x0/0x
3c)
[   20.776947] Code: ea00000d e5941248 e3a00000 e584600c (e5911008) 
[   20.783599] ---[ end trace bcb6e89e4ea810ae ]---



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-17 13:54           ` Tomi Valkeinen
@ 2012-08-20  8:42             ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-20  8:42 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1851 bytes --]

On Fri, 2012-08-17 at 16:54 +0300, Tomi Valkeinen wrote:
> On Thu, 2012-08-16 at 16:48 +0530, Chandrabhanu Mahapatra wrote:
> > 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>
> 
> > +static int __init dss_init_features(struct device *dev)
> > +{
> > +	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
> > +	if (!dss.feat) {
> > +		dev_err(dev, "Failed to allocate local DSS Features\n");
> > +		return -ENOMEM;
> > +	}
> > +
> > +	if (cpu_is_omap24xx())
> > +		dss.feat = &omap24xx_dss_features;
> > +	else if (cpu_is_omap34xx())
> > +		dss.feat = &omap34xx_dss_features;
> > +	else if (cpu_is_omap3630())
> > +		dss.feat = &omap3630_dss_features;
> > +	else if (cpu_is_omap44xx())
> > +		dss.feat = &omap44xx_dss_features;
> > +	else
> > +		return -ENODEV;
> > +
> > +	return 0;
> > +}
> 
> This is not correct (and same problem in dispc). You allocate the feat
> struct and assign the pointer to dss.feat, but then overwrite dss.feat
> pointer with the pointer to omap24xx_dss_features (which is freed
> later). You need to memcpy it.
> 
> I also get a crash on omap3 overo board when loading omapdss:

The crash happens because dss_get_clocks uses the feat stuff, but the
dss_init_features is only called later. Did you test this? I can't see
how that can work on any board.

Also, in the current place you have dss_init_features call, in case
there's an error you can't just return, you need to release the
resources. The same problem is in the dispc.c.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-20  8:42             ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-20  8:42 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1851 bytes --]

On Fri, 2012-08-17 at 16:54 +0300, Tomi Valkeinen wrote:
> On Thu, 2012-08-16 at 16:48 +0530, Chandrabhanu Mahapatra wrote:
> > 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>
> 
> > +static int __init dss_init_features(struct device *dev)
> > +{
> > +	dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
> > +	if (!dss.feat) {
> > +		dev_err(dev, "Failed to allocate local DSS Features\n");
> > +		return -ENOMEM;
> > +	}
> > +
> > +	if (cpu_is_omap24xx())
> > +		dss.feat = &omap24xx_dss_features;
> > +	else if (cpu_is_omap34xx())
> > +		dss.feat = &omap34xx_dss_features;
> > +	else if (cpu_is_omap3630())
> > +		dss.feat = &omap3630_dss_features;
> > +	else if (cpu_is_omap44xx())
> > +		dss.feat = &omap44xx_dss_features;
> > +	else
> > +		return -ENODEV;
> > +
> > +	return 0;
> > +}
> 
> This is not correct (and same problem in dispc). You allocate the feat
> struct and assign the pointer to dss.feat, but then overwrite dss.feat
> pointer with the pointer to omap24xx_dss_features (which is freed
> later). You need to memcpy it.
> 
> I also get a crash on omap3 overo board when loading omapdss:

The crash happens because dss_get_clocks uses the feat stuff, but the
dss_init_features is only called later. Did you test this? I can't see
how that can work on any board.

Also, in the current place you have dss_init_features call, in case
there's an error you can't just return, you need to release the
resources. The same problem is in the dispc.c.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-20  8:42             ` Tomi Valkeinen
@ 2012-08-20 10:48               ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-20 10:36 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Mon, Aug 20, 2012 at 2:12 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Fri, 2012-08-17 at 16:54 +0300, Tomi Valkeinen wrote:
>> On Thu, 2012-08-16 at 16:48 +0530, Chandrabhanu Mahapatra wrote:
>> > 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>
>>
>> > +static int __init dss_init_features(struct device *dev)
>> > +{
>> > +   dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
>> > +   if (!dss.feat) {
>> > +           dev_err(dev, "Failed to allocate local DSS Features\n");
>> > +           return -ENOMEM;
>> > +   }
>> > +
>> > +   if (cpu_is_omap24xx())
>> > +           dss.feat = &omap24xx_dss_features;
>> > +   else if (cpu_is_omap34xx())
>> > +           dss.feat = &omap34xx_dss_features;
>> > +   else if (cpu_is_omap3630())
>> > +           dss.feat = &omap3630_dss_features;
>> > +   else if (cpu_is_omap44xx())
>> > +           dss.feat = &omap44xx_dss_features;
>> > +   else
>> > +           return -ENODEV;
>> > +
>> > +   return 0;
>> > +}
>>
>> This is not correct (and same problem in dispc). You allocate the feat
>> struct and assign the pointer to dss.feat, but then overwrite dss.feat
>> pointer with the pointer to omap24xx_dss_features (which is freed
>> later). You need to memcpy it.
>>

Ok.

>> I also get a crash on omap3 overo board when loading omapdss:
>

During recent tests I never saw the crash happen. The kernel used to
freeze during booting after printing
"Uncompressing Linux... done, booting the kernel."

> The crash happens because dss_get_clocks uses the feat stuff, but the
> dss_init_features is only called later. Did you test this? I can't see
> how that can work on any board.
>

Thanks for pointing that out. Correcting above fixed the problem.

> Also, in the current place you have dss_init_features call, in case
> there's an error you can't just return, you need to release the
> resources. The same problem is in the dispc.c.
>
>  Tomi
>

By releasing resources did you mean the dss.feat memory? I think
dss_init_features call is wrongly placed and should be placed at the
very beginning of the probe function.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-20 10:48               ` Mahapatra, Chandrabhanu
@ 2012-08-20 10:46                 ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-20 10:46 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 376 bytes --]

On Mon, 2012-08-20 at 16:06 +0530, Mahapatra, Chandrabhanu wrote:

> By releasing resources did you mean the dss.feat memory? I think
> dss_init_features call is wrongly placed and should be placed at the
> very beginning of the probe function.

I meant e.g. pm_runtime_disable() etc. But if the call is moved t the
beginning, there's nothing to release.

 Tomi



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-20 10:46                 ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-20 10:46 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 376 bytes --]

On Mon, 2012-08-20 at 16:06 +0530, Mahapatra, Chandrabhanu wrote:

> By releasing resources did you mean the dss.feat memory? I think
> dss_init_features call is wrongly placed and should be placed at the
> very beginning of the probe function.

I meant e.g. pm_runtime_disable() etc. But if the call is moved t the
beginning, there's nothing to release.

 Tomi



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V4 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-20 10:48               ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-20 10:48 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Mon, Aug 20, 2012 at 2:12 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Fri, 2012-08-17 at 16:54 +0300, Tomi Valkeinen wrote:
>> On Thu, 2012-08-16 at 16:48 +0530, Chandrabhanu Mahapatra wrote:
>> > 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>
>>
>> > +static int __init dss_init_features(struct device *dev)
>> > +{
>> > +   dss.feat = devm_kzalloc(dev, sizeof(*dss.feat), GFP_KERNEL);
>> > +   if (!dss.feat) {
>> > +           dev_err(dev, "Failed to allocate local DSS Features\n");
>> > +           return -ENOMEM;
>> > +   }
>> > +
>> > +   if (cpu_is_omap24xx())
>> > +           dss.feat = &omap24xx_dss_features;
>> > +   else if (cpu_is_omap34xx())
>> > +           dss.feat = &omap34xx_dss_features;
>> > +   else if (cpu_is_omap3630())
>> > +           dss.feat = &omap3630_dss_features;
>> > +   else if (cpu_is_omap44xx())
>> > +           dss.feat = &omap44xx_dss_features;
>> > +   else
>> > +           return -ENODEV;
>> > +
>> > +   return 0;
>> > +}
>>
>> This is not correct (and same problem in dispc). You allocate the feat
>> struct and assign the pointer to dss.feat, but then overwrite dss.feat
>> pointer with the pointer to omap24xx_dss_features (which is freed
>> later). You need to memcpy it.
>>

Ok.

>> I also get a crash on omap3 overo board when loading omapdss:
>

During recent tests I never saw the crash happen. The kernel used to
freeze during booting after printing
"Uncompressing Linux... done, booting the kernel."

> The crash happens because dss_get_clocks uses the feat stuff, but the
> dss_init_features is only called later. Did you test this? I can't see
> how that can work on any board.
>

Thanks for pointing that out. Correcting above fixed the problem.

> Also, in the current place you have dss_init_features call, in case
> there's an error you can't just return, you need to release the
> resources. The same problem is in the dispc.c.
>
>  Tomi
>

By releasing resources did you mean the dss.feat memory? I think
dss_init_features call is wrongly placed and should be placed at the
very beginning of the probe function.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-07  8:39 ` Chandrabhanu Mahapatra
@ 2012-08-20 13:33   ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:21 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Hi everyone,
this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
more generic.

The 1st patch cleans up cpu_is checks from DISPC code.
The 2nd patch removes unused functions from DSS code.
The 3rd patch cleans up cpu_is checks from DSS code.
The 4th patch removes cpu_is checks from VENC code.
The 5th patch disables VENC support on OMAP4.
The 6th patch removes cpu_is checks from DPI code and replaces it with a
dss feature.

Changes with respect to V1 series:
 1st patch :
	* moved dispc_ops structure definitions from dss_features.c to dispc.c
	  and renamed it to dispc_features
	* moved dispc_features definitions close to dispc_init_features() thereby
	  eliminating various functions declarations from top of dispc.c
	* used __initconst before dispc_features definitions and __init before
	  dispc_init_features()
	* removed definitions of _dispc_lcd_timings_ok_24xx,
	  _dispc_lcd_timings_ok_44xx, _dispc_mgr_set_lcd_timings_hv_24xx and
	  _dispc_mgr_set_lcd_timings_hv_44xx replacing them with appropiate variables
	* renamed various dispc_features structures to give consistent naming

 3rd patch :
	* moved dss_ops structure definitions from dss_features.c to dss.c and
	  renamed it to dss_features
	* removed all functions from dss_features structure and replaced them with
	  appropiate variables
	* used __initconst before dss_features definitions and __init before 
	  dss_init_features()
	* renamed various dss_features structures to give consistent naming
	* renamed factor variable of dss_features structure to dss_fck_multiplier

All your comments and suggestions are welcome.

Refenence Tree:
git@gitorious.org:~chandrabhanu/linux-omap-dss2/chandrabhanus-linux.git dss_cleanup

Chandrabhanu Mahapatra (6):
  OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  OMAPDSS: DSS: Remove redundant functions
  OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  OMAPDSS: VENC: Remove cpu_is_xxxx checks
  ARM: OMAP: Disable venc for OMAP4
  OMAPDSS: DPI: Remove cpu_is_xxxx checks

 arch/arm/mach-omap2/display.c          |    1 -
 drivers/video/omap2/dss/dispc.c        |  433 ++++++++++++++++++++------------
 drivers/video/omap2/dss/dpi.c          |   12 +-
 drivers/video/omap2/dss/dss.c          |  162 ++++++------
 drivers/video/omap2/dss/dss.h          |    2 -
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/venc.c         |   11 -
 8 files changed, 363 insertions(+), 260 deletions(-)

-- 
1.7.10


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
@ 2012-08-20 13:34     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:22 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  433 +++++++++++++++++++++++++--------------
 1 file changed, 278 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ff52702..3fad33a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int hp_max;
+	int vp_max;
+	int sw_max;
+	int sw_start;
+	int fp_start;
+	int bp_start;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth =
+				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
 	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth =
-				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width == out_width && height == out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,79 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct dispc_features omap24xx_dispc_feats __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap44xx_dispc_feats __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	struct dispc_features *feat = devm_kzalloc(dev, sizeof(*feat),
+								GFP_KERNEL);
+	if (!feat) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		memcpy(feat, &omap24xx_dispc_feats, sizeof(*feat));
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			memcpy(feat, &omap34xx_rev1_0_dispc_feats,
+							sizeof(*feat));
+		else
+			memcpy(feat, &omap34xx_rev3_0_dispc_feats,
+							sizeof(*feat));
+	} else if (cpu_is_omap44xx()) {
+		memcpy(feat, &omap44xx_dispc_feats, sizeof(*feat));
+	} else {
+		return -ENODEV;
+	}
+
+	dispc.feat = feat;
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3681,6 +3800,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.pdev = pdev;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	spin_lock_init(&dispc.irq_lock);
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 2/6] OMAPDSS: DSS: Remove redundant functions
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
@ 2012-08-20 13:35     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:23 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Functions dss_calc_clock_rates() and dss_get_clock_div() are removed as these
functions have become redundant and no longer used.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |   45 -----------------------------------------
 drivers/video/omap2/dss/dss.h |    2 --
 2 files changed, 47 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 4491ab7..10566ae 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 	}
 }
 
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-		u16 fck_div_max = 16;
-
-		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));
-
-		cinfo->fck = prate / cinfo->fck_div;
-	} else {
-		if (cinfo->fck_div != 0)
-			return -EINVAL;
-		cinfo->fck = clk_get_rate(dss.dss_clk);
-	}
-
-	return 0;
-}
-
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
 	if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
 	return 0;
 }
 
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
-	cinfo->fck = clk_get_rate(dss.dss_clk);
-
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			cinfo->fck_div = prate / (cinfo->fck);
-		else
-			cinfo->fck_div = prate / (cinfo->fck / 2);
-	} else {
-		cinfo->fck_div = 0;
-	}
-
-	return 0;
-}
-
 unsigned long dss_get_dpll4_rate(void)
 {
 	if (dss.dpll4_m4_ck)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f67afe7..33c0952 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -296,9 +296,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
@ 2012-08-20 13:35     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:23 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
 1 file changed, 76 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 10566ae..f6d3d0a 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/gfp.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,12 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u16 fck_div_max;
+	int dss_fck_multiplier;
+	char *clk_name;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +90,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +100,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap24xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct dss_features omap34xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap3630_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap44xx_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__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)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +291,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->dss_fck_multiplier, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +494,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +504,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck == dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck == fck)) {
+	if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
+		dss.cache_dss_cinfo.fck == fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +542,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max == 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->dss_fck_multiplier;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -645,22 +662,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -716,6 +722,31 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	struct dss_features *feat = devm_kzalloc(dev, sizeof(*feat),
+								GFP_KERNEL);
+	if (!feat) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		memcpy(feat, &omap24xx_dss_feats, sizeof(*feat));
+	else if (cpu_is_omap34xx())
+		memcpy(feat, &omap34xx_dss_feats, sizeof(*feat));
+	else if (cpu_is_omap3630())
+		memcpy(feat, &omap3630_dss_feats, sizeof(*feat));
+	else if (cpu_is_omap44xx())
+		memcpy(feat, &omap44xx_dss_feats, sizeof(*feat));
+	else
+		return -ENODEV;
+
+	dss.feat = feat;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -725,6 +756,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 
 	dss.pdev = pdev;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
 	if (!dss_mem) {
 		DSSERR("can't get IORESOURCE_MEM DSS\n");
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
@ 2012-08-20 13:36     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:24 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

OMAP4 checks are removed from VENC to provide it a cleaner interface. These
checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
"OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
from crashing OMAP4 kernel. An alternative approach is used to do the same in
later patches.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/venc.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..8fc165a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -752,11 +752,6 @@ static void venc_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
-	if (cpu_is_omap44xx()) {
-		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
-		return;
-	}
-
 	if (venc_runtime_get())
 		return;
 
@@ -971,16 +966,10 @@ static struct platform_driver omap_venchw_driver = {
 
 int __init venc_init_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return 0;
-
 	return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
 }
 
 void __exit venc_uninit_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return;
-
 	platform_driver_unregister(&omap_venchw_driver);
 }
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
@ 2012-08-20 13:36     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:24 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
@ 2012-08-20 13:36     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:24 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The OMAP3 checks have been removed and replaced by a dss feature
FEAT_DPI_USES_VDDS_DSI for cleaner implementation. The patches
"OMAP: DSS2: enable VDDS_DSI when using DPI" (8a2cfea8cc) by Tomi Valkeinen
<tomi.valkeinen@nokia.com> and "ARM: omap: fix oops in
drivers/video/omap2/dss/dpi.c" (4041071571) by Russell King
<rmk+kernel@arm.linux.org.uk> had introduced these checks. As it is evident
from these patches a dependency exists for some DSS pins on VDDS_DSI which is
better shown by dss feature FEAT_DPI_USES_VDDS_DSI.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dpi.c          |   12 +++++++-----
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 3266be2..b97f7b8 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -34,6 +34,7 @@
 #include <plat/cpu.h>
 
 #include "dss.h"
+#include "dss_features.h"
 
 static struct {
 	struct regulator *vdds_dsi_reg;
@@ -169,7 +170,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
 		return -ENODEV;
 	}
@@ -185,7 +186,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -229,7 +230,7 @@ err_dsi_pll_init:
 err_get_dsi:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
@@ -250,7 +251,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
@@ -329,7 +330,8 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+					dpi.vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..2fe39d6 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -373,6 +373,7 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
 	FEAT_ALPHA_FIXED_ZORDER,
 	FEAT_FIFO_MERGE,
 	FEAT_OMAP3_DSI_FIFO_BUG,
+	FEAT_DPI_USES_VDDS_DSI,
 };
 
 static const enum dss_feat_id omap3630_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..26d43a4 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@ enum dss_feat_id {
 	FEAT_DSI_VC_OCP_WIDTH,
 	FEAT_DSI_REVERSE_TXCLKESC,
 	FEAT_DSI_GNQ,
+	FEAT_DPI_USES_VDDS_DSI,
 	FEAT_HDMI_CTS_SWMODE,
 	FEAT_HDMI_AUDIO_USE_MCLK,
 	FEAT_HANDLE_UV_SEPARATE,
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-20 13:33   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:33 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Hi everyone,
this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
more generic.

The 1st patch cleans up cpu_is checks from DISPC code.
The 2nd patch removes unused functions from DSS code.
The 3rd patch cleans up cpu_is checks from DSS code.
The 4th patch removes cpu_is checks from VENC code.
The 5th patch disables VENC support on OMAP4.
The 6th patch removes cpu_is checks from DPI code and replaces it with a
dss feature.

Changes with respect to V1 series:
 1st patch :
	* moved dispc_ops structure definitions from dss_features.c to dispc.c
	  and renamed it to dispc_features
	* moved dispc_features definitions close to dispc_init_features() thereby
	  eliminating various functions declarations from top of dispc.c
	* used __initconst before dispc_features definitions and __init before
	  dispc_init_features()
	* removed definitions of _dispc_lcd_timings_ok_24xx,
	  _dispc_lcd_timings_ok_44xx, _dispc_mgr_set_lcd_timings_hv_24xx and
	  _dispc_mgr_set_lcd_timings_hv_44xx replacing them with appropiate variables
	* renamed various dispc_features structures to give consistent naming

 3rd patch :
	* moved dss_ops structure definitions from dss_features.c to dss.c and
	  renamed it to dss_features
	* removed all functions from dss_features structure and replaced them with
	  appropiate variables
	* used __initconst before dss_features definitions and __init before 
	  dss_init_features()
	* renamed various dss_features structures to give consistent naming
	* renamed factor variable of dss_features structure to dss_fck_multiplier

All your comments and suggestions are welcome.

Refenence Tree:
git@gitorious.org:~chandrabhanu/linux-omap-dss2/chandrabhanus-linux.git dss_cleanup

Chandrabhanu Mahapatra (6):
  OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  OMAPDSS: DSS: Remove redundant functions
  OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  OMAPDSS: VENC: Remove cpu_is_xxxx checks
  ARM: OMAP: Disable venc for OMAP4
  OMAPDSS: DPI: Remove cpu_is_xxxx checks

 arch/arm/mach-omap2/display.c          |    1 -
 drivers/video/omap2/dss/dispc.c        |  433 ++++++++++++++++++++------------
 drivers/video/omap2/dss/dpi.c          |   12 +-
 drivers/video/omap2/dss/dss.c          |  162 ++++++------
 drivers/video/omap2/dss/dss.h          |    2 -
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/venc.c         |   11 -
 8 files changed, 363 insertions(+), 260 deletions(-)

-- 
1.7.10


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-20 13:34     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:34 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  433 +++++++++++++++++++++++++--------------
 1 file changed, 278 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ff52702..3fad33a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	int hp_max;
+	int vp_max;
+	int sw_max;
+	int sw_start;
+	int fp_start;
+	int bp_start;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth +				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
 	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth -				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width = out_width && height = out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,79 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct dispc_features omap24xx_dispc_feats __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
+	.hp_max			=	256,
+	.vp_max			=	255,
+	.sw_max			=	64,
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap44xx_dispc_feats __initconst = {
+	.hp_max			=	4096,
+	.vp_max			=	4095,
+	.sw_max			=	256,
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	struct dispc_features *feat = devm_kzalloc(dev, sizeof(*feat),
+								GFP_KERNEL);
+	if (!feat) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		memcpy(feat, &omap24xx_dispc_feats, sizeof(*feat));
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			memcpy(feat, &omap34xx_rev1_0_dispc_feats,
+							sizeof(*feat));
+		else
+			memcpy(feat, &omap34xx_rev3_0_dispc_feats,
+							sizeof(*feat));
+	} else if (cpu_is_omap44xx()) {
+		memcpy(feat, &omap44xx_dispc_feats, sizeof(*feat));
+	} else {
+		return -ENODEV;
+	}
+
+	dispc.feat = feat;
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3681,6 +3800,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.pdev = pdev;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	spin_lock_init(&dispc.irq_lock);
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 2/6] OMAPDSS: DSS: Remove redundant functions
@ 2012-08-20 13:35     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:35 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Functions dss_calc_clock_rates() and dss_get_clock_div() are removed as these
functions have become redundant and no longer used.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |   45 -----------------------------------------
 drivers/video/omap2/dss/dss.h |    2 --
 2 files changed, 47 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 4491ab7..10566ae 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 	}
 }
 
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-		u16 fck_div_max = 16;
-
-		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));
-
-		cinfo->fck = prate / cinfo->fck_div;
-	} else {
-		if (cinfo->fck_div != 0)
-			return -EINVAL;
-		cinfo->fck = clk_get_rate(dss.dss_clk);
-	}
-
-	return 0;
-}
-
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
 	if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
 	return 0;
 }
 
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
-	cinfo->fck = clk_get_rate(dss.dss_clk);
-
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			cinfo->fck_div = prate / (cinfo->fck);
-		else
-			cinfo->fck_div = prate / (cinfo->fck / 2);
-	} else {
-		cinfo->fck_div = 0;
-	}
-
-	return 0;
-}
-
 unsigned long dss_get_dpll4_rate(void)
 {
 	if (dss.dpll4_m4_ck)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f67afe7..33c0952 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -296,9 +296,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-20 13:35     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:35 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
 1 file changed, 76 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 10566ae..f6d3d0a 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/gfp.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,12 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u16 fck_div_max;
+	int dss_fck_multiplier;
+	char *clk_name;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +90,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +100,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap24xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct dss_features omap34xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap3630_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap44xx_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__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)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +291,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->dss_fck_multiplier, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +494,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +504,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck = dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate = dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck = fck)) {
+	if (req_pck = dss.cache_req_pck && prate = dss.cache_prate &&
+		dss.cache_dss_cinfo.fck = fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +542,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max = 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->dss_fck_multiplier;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -645,22 +662,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -716,6 +722,31 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	struct dss_features *feat = devm_kzalloc(dev, sizeof(*feat),
+								GFP_KERNEL);
+	if (!feat) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		memcpy(feat, &omap24xx_dss_feats, sizeof(*feat));
+	else if (cpu_is_omap34xx())
+		memcpy(feat, &omap34xx_dss_feats, sizeof(*feat));
+	else if (cpu_is_omap3630())
+		memcpy(feat, &omap3630_dss_feats, sizeof(*feat));
+	else if (cpu_is_omap44xx())
+		memcpy(feat, &omap44xx_dss_feats, sizeof(*feat));
+	else
+		return -ENODEV;
+
+	dss.feat = feat;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -725,6 +756,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 
 	dss.pdev = pdev;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
 	if (!dss_mem) {
 		DSSERR("can't get IORESOURCE_MEM DSS\n");
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 4/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
@ 2012-08-20 13:36     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:36 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

OMAP4 checks are removed from VENC to provide it a cleaner interface. These
checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
"OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
from crashing OMAP4 kernel. An alternative approach is used to do the same in
later patches.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/venc.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..8fc165a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -752,11 +752,6 @@ static void venc_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
-	if (cpu_is_omap44xx()) {
-		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
-		return;
-	}
-
 	if (venc_runtime_get())
 		return;
 
@@ -971,16 +966,10 @@ static struct platform_driver omap_venchw_driver = {
 
 int __init venc_init_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return 0;
-
 	return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
 }
 
 void __exit venc_uninit_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return;
-
 	platform_driver_unregister(&omap_venchw_driver);
 }
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4
@ 2012-08-20 13:36     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:36 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V5 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks
@ 2012-08-20 13:36     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-20 13:36 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The OMAP3 checks have been removed and replaced by a dss feature
FEAT_DPI_USES_VDDS_DSI for cleaner implementation. The patches
"OMAP: DSS2: enable VDDS_DSI when using DPI" (8a2cfea8cc) by Tomi Valkeinen
<tomi.valkeinen@nokia.com> and "ARM: omap: fix oops in
drivers/video/omap2/dss/dpi.c" (4041071571) by Russell King
<rmk+kernel@arm.linux.org.uk> had introduced these checks. As it is evident
from these patches a dependency exists for some DSS pins on VDDS_DSI which is
better shown by dss feature FEAT_DPI_USES_VDDS_DSI.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dpi.c          |   12 +++++++-----
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 3266be2..b97f7b8 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -34,6 +34,7 @@
 #include <plat/cpu.h>
 
 #include "dss.h"
+#include "dss_features.h"
 
 static struct {
 	struct regulator *vdds_dsi_reg;
@@ -169,7 +170,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
 		return -ENODEV;
 	}
@@ -185,7 +186,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -229,7 +230,7 @@ err_dsi_pll_init:
 err_get_dsi:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
@@ -250,7 +251,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
@@ -329,7 +330,8 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg = NULL) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+					dpi.vdds_dsi_reg = NULL) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..2fe39d6 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -373,6 +373,7 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
 	FEAT_ALPHA_FIXED_ZORDER,
 	FEAT_FIFO_MERGE,
 	FEAT_OMAP3_DSI_FIFO_BUG,
+	FEAT_DPI_USES_VDDS_DSI,
 };
 
 static const enum dss_feat_id omap3630_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..26d43a4 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@ enum dss_feat_id {
 	FEAT_DSI_VC_OCP_WIDTH,
 	FEAT_DSI_REVERSE_TXCLKESC,
 	FEAT_DSI_GNQ,
+	FEAT_DPI_USES_VDDS_DSI,
 	FEAT_HDMI_CTS_SWMODE,
 	FEAT_HDMI_AUDIO_USE_MCLK,
 	FEAT_HANDLE_UV_SEPARATE,
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-20 13:34     ` Chandrabhanu Mahapatra
@ 2012-08-21 10:31       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 10:31 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2558 bytes --]

On Mon, 2012-08-20 at 18:52 +0530, Chandrabhanu Mahapatra wrote:
> All the cpu_is checks have been moved to dispc_init_features function providing
> a much more generic and cleaner interface. The OMAP version and revision
> specific functions and data are initialized by dispc_features structure which is
> local to dispc.c.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dispc.c |  433 +++++++++++++++++++++++++--------------
>  1 file changed, 278 insertions(+), 155 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index ff52702..3fad33a 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -81,6 +81,23 @@ struct dispc_irq_stats {
>  	unsigned irqs[32];
>  };
>  
> +struct dispc_features {
> +	int hp_max;
> +	int vp_max;
> +	int sw_max;
> +	int sw_start;
> +	int fp_start;
> +	int bp_start;

Here you could use a bit smaller datatype. u16 should probably be more
than enough.

> +static int __init dispc_init_features(struct device *dev)
> +{
> +	struct dispc_features *feat = devm_kzalloc(dev, sizeof(*feat),
> +								GFP_KERNEL);
> +	if (!feat) {
> +		dev_err(dev, "Failed to allocate DISPC Features\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (cpu_is_omap24xx()) {
> +		memcpy(feat, &omap24xx_dispc_feats, sizeof(*feat));
> +	} else if (cpu_is_omap34xx()) {
> +		if (omap_rev() < OMAP3430_REV_ES3_0)
> +			memcpy(feat, &omap34xx_rev1_0_dispc_feats,
> +							sizeof(*feat));
> +		else
> +			memcpy(feat, &omap34xx_rev3_0_dispc_feats,
> +							sizeof(*feat));
> +	} else if (cpu_is_omap44xx()) {
> +		memcpy(feat, &omap44xx_dispc_feats, sizeof(*feat));
> +	} else {
> +		return -ENODEV;
> +	}
> +
> +	dispc.feat = feat;
> +
> +	return 0;
> +}

This becomes much cleaner with something like the following (same could
be used in dss.c also):

	const struct dispc_features *src;
	struct dispc_features *dst;

	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
	if (!dsst) {
		dev_err(dev, "Failed to allocate DISPC Features\n");
		return -ENOMEM;
	}

	if (cpu_is_omap24xx()) {
		src = &omap24xx_dispc_feats;
	} else if (cpu_is_omap34xx()) {
		if (omap_rev() < OMAP3430_REV_ES3_0)
			src = &omap34xx_rev1_0_dispc_feats;
		else
			src = &omap34xx_rev3_0_dispc_feats;
	} else if (cpu_is_omap44xx()) {
		src = &omap44xx_dispc_feats;
	} else {
		return -ENODEV;
	}

	memcpy(dst, src, sizeof(*dst));

	dispc.feat = dst;

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-21 10:31       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 10:31 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2558 bytes --]

On Mon, 2012-08-20 at 18:52 +0530, Chandrabhanu Mahapatra wrote:
> All the cpu_is checks have been moved to dispc_init_features function providing
> a much more generic and cleaner interface. The OMAP version and revision
> specific functions and data are initialized by dispc_features structure which is
> local to dispc.c.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dispc.c |  433 +++++++++++++++++++++++++--------------
>  1 file changed, 278 insertions(+), 155 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index ff52702..3fad33a 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -81,6 +81,23 @@ struct dispc_irq_stats {
>  	unsigned irqs[32];
>  };
>  
> +struct dispc_features {
> +	int hp_max;
> +	int vp_max;
> +	int sw_max;
> +	int sw_start;
> +	int fp_start;
> +	int bp_start;

Here you could use a bit smaller datatype. u16 should probably be more
than enough.

> +static int __init dispc_init_features(struct device *dev)
> +{
> +	struct dispc_features *feat = devm_kzalloc(dev, sizeof(*feat),
> +								GFP_KERNEL);
> +	if (!feat) {
> +		dev_err(dev, "Failed to allocate DISPC Features\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (cpu_is_omap24xx()) {
> +		memcpy(feat, &omap24xx_dispc_feats, sizeof(*feat));
> +	} else if (cpu_is_omap34xx()) {
> +		if (omap_rev() < OMAP3430_REV_ES3_0)
> +			memcpy(feat, &omap34xx_rev1_0_dispc_feats,
> +							sizeof(*feat));
> +		else
> +			memcpy(feat, &omap34xx_rev3_0_dispc_feats,
> +							sizeof(*feat));
> +	} else if (cpu_is_omap44xx()) {
> +		memcpy(feat, &omap44xx_dispc_feats, sizeof(*feat));
> +	} else {
> +		return -ENODEV;
> +	}
> +
> +	dispc.feat = feat;
> +
> +	return 0;
> +}

This becomes much cleaner with something like the following (same could
be used in dss.c also):

	const struct dispc_features *src;
	struct dispc_features *dst;

	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
	if (!dsst) {
		dev_err(dev, "Failed to allocate DISPC Features\n");
		return -ENOMEM;
	}

	if (cpu_is_omap24xx()) {
		src = &omap24xx_dispc_feats;
	} else if (cpu_is_omap34xx()) {
		if (omap_rev() < OMAP3430_REV_ES3_0)
			src = &omap34xx_rev1_0_dispc_feats;
		else
			src = &omap34xx_rev3_0_dispc_feats;
	} else if (cpu_is_omap44xx()) {
		src = &omap44xx_dispc_feats;
	} else {
		return -ENODEV;
	}

	memcpy(dst, src, sizeof(*dst));

	dispc.feat = dst;

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4
  2012-08-20 13:36     ` Chandrabhanu Mahapatra
@ 2012-08-21 10:32       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 10:32 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tony, paul, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1288 bytes --]

On Mon, 2012-08-20 at 18:54 +0530, Chandrabhanu Mahapatra wrote:
> This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
> prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
> VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
> of a device for VENC on OMAP4.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  arch/arm/mach-omap2/display.c |    1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
> index af1ed7d..ee40739 100644
> --- a/arch/arm/mach-omap2/display.c
> +++ b/arch/arm/mach-omap2/display.c
> @@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
>  	{ "dss_core", "omapdss_dss", -1 },
>  	{ "dss_dispc", "omapdss_dispc", -1 },
>  	{ "dss_rfbi", "omapdss_rfbi", -1 },
> -	{ "dss_venc", "omapdss_venc", -1 },
>  	{ "dss_dsi1", "omapdss_dsi", 0 },
>  	{ "dss_dsi2", "omapdss_dsi", 1 },
>  	{ "dss_hdmi", "omapdss_hdmi", -1 },

You need to reorder this and the previous patch. If you first remove the
workaround from the previous patch, the kernel will crash if after that
patch. So this one should be before the previous patch.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4
@ 2012-08-21 10:32       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 10:32 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tony, paul, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1288 bytes --]

On Mon, 2012-08-20 at 18:54 +0530, Chandrabhanu Mahapatra wrote:
> This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
> prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
> VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
> of a device for VENC on OMAP4.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  arch/arm/mach-omap2/display.c |    1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
> index af1ed7d..ee40739 100644
> --- a/arch/arm/mach-omap2/display.c
> +++ b/arch/arm/mach-omap2/display.c
> @@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
>  	{ "dss_core", "omapdss_dss", -1 },
>  	{ "dss_dispc", "omapdss_dispc", -1 },
>  	{ "dss_rfbi", "omapdss_rfbi", -1 },
> -	{ "dss_venc", "omapdss_venc", -1 },
>  	{ "dss_dsi1", "omapdss_dsi", 0 },
>  	{ "dss_dsi2", "omapdss_dsi", 1 },
>  	{ "dss_hdmi", "omapdss_hdmi", -1 },

You need to reorder this and the previous patch. If you first remove the
workaround from the previous patch, the kernel will crash if after that
patch. So this one should be before the previous patch.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-20 13:35     ` Chandrabhanu Mahapatra
@ 2012-08-21 10:35       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 10:35 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1208 bytes --]

On Mon, 2012-08-20 at 18:53 +0530, Chandrabhanu Mahapatra wrote:
> 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>
> ---
>  drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
>  1 file changed, 76 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 10566ae..f6d3d0a 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -31,6 +31,7 @@
>  #include <linux/clk.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/gfp.h>
>  
>  #include <video/omapdss.h>
>  
> @@ -65,6 +66,12 @@ struct dss_reg {
>  static int dss_runtime_get(void);
>  static void dss_runtime_put(void);
>  
> +struct dss_features {
> +	u16 fck_div_max;
> +	int dss_fck_multiplier;
> +	char *clk_name;

const char *

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-21 10:35       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 10:35 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1208 bytes --]

On Mon, 2012-08-20 at 18:53 +0530, Chandrabhanu Mahapatra wrote:
> 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>
> ---
>  drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
>  1 file changed, 76 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 10566ae..f6d3d0a 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -31,6 +31,7 @@
>  #include <linux/clk.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/gfp.h>
>  
>  #include <video/omapdss.h>
>  
> @@ -65,6 +66,12 @@ struct dss_reg {
>  static int dss_runtime_get(void);
>  static void dss_runtime_put(void);
>  
> +struct dss_features {
> +	u16 fck_div_max;
> +	int dss_fck_multiplier;
> +	char *clk_name;

const char *

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-21 10:35       ` Tomi Valkeinen
@ 2012-08-21 11:18         ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-21 11:06 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Tue, Aug 21, 2012 at 4:05 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-20 at 18:53 +0530, Chandrabhanu Mahapatra wrote:
>> 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>
>> ---
>>  drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
>>  1 file changed, 76 insertions(+), 41 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 10566ae..f6d3d0a 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -31,6 +31,7 @@
>>  #include <linux/clk.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/gfp.h>
>>
>>  #include <video/omapdss.h>
>>
>> @@ -65,6 +66,12 @@ struct dss_reg {
>>  static int dss_runtime_get(void);
>>  static void dss_runtime_put(void);
>>
>> +struct dss_features {
>> +     u16 fck_div_max;
>> +     int dss_fck_multiplier;
>> +     char *clk_name;
>
> const char *
>
>  Tomi
>

All the values are const. So we have a const pointer dss.feat to hold
this structure. Is a separate
const char *clk_name required?

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4
  2012-08-21 10:32       ` Tomi Valkeinen
@ 2012-08-21 11:25         ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-21 11:13 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: tony, paul, linux-omap, linux-fbdev

On Tue, Aug 21, 2012 at 4:02 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-20 at 18:54 +0530, Chandrabhanu Mahapatra wrote:
>> This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
>> prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
>> VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
>> of a device for VENC on OMAP4.
>>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  arch/arm/mach-omap2/display.c |    1 -
>>  1 file changed, 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
>> index af1ed7d..ee40739 100644
>> --- a/arch/arm/mach-omap2/display.c
>> +++ b/arch/arm/mach-omap2/display.c
>> @@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
>>       { "dss_core", "omapdss_dss", -1 },
>>       { "dss_dispc", "omapdss_dispc", -1 },
>>       { "dss_rfbi", "omapdss_rfbi", -1 },
>> -     { "dss_venc", "omapdss_venc", -1 },
>>       { "dss_dsi1", "omapdss_dsi", 0 },
>>       { "dss_dsi2", "omapdss_dsi", 1 },
>>       { "dss_hdmi", "omapdss_hdmi", -1 },
>
> You need to reorder this and the previous patch. If you first remove the
> workaround from the previous patch, the kernel will crash if after that
> patch. So this one should be before the previous patch.
>
>  Tomi
>

Ok.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-21 11:18         ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-21 11:18 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Tue, Aug 21, 2012 at 4:05 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-20 at 18:53 +0530, Chandrabhanu Mahapatra wrote:
>> 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>
>> ---
>>  drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
>>  1 file changed, 76 insertions(+), 41 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 10566ae..f6d3d0a 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -31,6 +31,7 @@
>>  #include <linux/clk.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/gfp.h>
>>
>>  #include <video/omapdss.h>
>>
>> @@ -65,6 +66,12 @@ struct dss_reg {
>>  static int dss_runtime_get(void);
>>  static void dss_runtime_put(void);
>>
>> +struct dss_features {
>> +     u16 fck_div_max;
>> +     int dss_fck_multiplier;
>> +     char *clk_name;
>
> const char *
>
>  Tomi
>

All the values are const. So we have a const pointer dss.feat to hold
this structure. Is a separate
const char *clk_name required?

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
  2012-08-21 10:31       ` Tomi Valkeinen
@ 2012-08-21 11:32         ` Mahapatra, Chandrabhanu
  -1 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-21 11:20 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Tue, Aug 21, 2012 at 4:01 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-20 at 18:52 +0530, Chandrabhanu Mahapatra wrote:
>> All the cpu_is checks have been moved to dispc_init_features function providing
>> a much more generic and cleaner interface. The OMAP version and revision
>> specific functions and data are initialized by dispc_features structure which is
>> local to dispc.c.
>>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dispc.c |  433 +++++++++++++++++++++++++--------------
>>  1 file changed, 278 insertions(+), 155 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
>> index ff52702..3fad33a 100644
>> --- a/drivers/video/omap2/dss/dispc.c
>> +++ b/drivers/video/omap2/dss/dispc.c
>> @@ -81,6 +81,23 @@ struct dispc_irq_stats {
>>       unsigned irqs[32];
>>  };
>>
>> +struct dispc_features {
>> +     int hp_max;
>> +     int vp_max;
>> +     int sw_max;
>> +     int sw_start;
>> +     int fp_start;
>> +     int bp_start;
>
> Here you could use a bit smaller datatype. u16 should probably be more
> than enough.
>

After looking at the values that these variables take I think hp_max,
vp_max and sw_max can be u16 and the rest three sw_start, fp_start and
bp_start can be u8.

>> +static int __init dispc_init_features(struct device *dev)
>> +{
>> +     struct dispc_features *feat = devm_kzalloc(dev, sizeof(*feat),
>> +                                                             GFP_KERNEL);
>> +     if (!feat) {
>> +             dev_err(dev, "Failed to allocate DISPC Features\n");
>> +             return -ENOMEM;
>> +     }
>> +
>> +     if (cpu_is_omap24xx()) {
>> +             memcpy(feat, &omap24xx_dispc_feats, sizeof(*feat));
>> +     } else if (cpu_is_omap34xx()) {
>> +             if (omap_rev() < OMAP3430_REV_ES3_0)
>> +                     memcpy(feat, &omap34xx_rev1_0_dispc_feats,
>> +                                                     sizeof(*feat));
>> +             else
>> +                     memcpy(feat, &omap34xx_rev3_0_dispc_feats,
>> +                                                     sizeof(*feat));
>> +     } else if (cpu_is_omap44xx()) {
>> +             memcpy(feat, &omap44xx_dispc_feats, sizeof(*feat));
>> +     } else {
>> +             return -ENODEV;
>> +     }
>> +
>> +     dispc.feat = feat;
>> +
>> +     return 0;
>> +}
>
> This becomes much cleaner with something like the following (same could
> be used in dss.c also):
>
>         const struct dispc_features *src;
>         struct dispc_features *dst;
>
>         dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
>         if (!dsst) {
>                 dev_err(dev, "Failed to allocate DISPC Features\n");
>                 return -ENOMEM;
>         }
>
>         if (cpu_is_omap24xx()) {
>                 src = &omap24xx_dispc_feats;
>         } else if (cpu_is_omap34xx()) {
>                 if (omap_rev() < OMAP3430_REV_ES3_0)
>                         src = &omap34xx_rev1_0_dispc_feats;
>                 else
>                         src = &omap34xx_rev3_0_dispc_feats;
>         } else if (cpu_is_omap44xx()) {
>                 src = &omap44xx_dispc_feats;
>         } else {
>                 return -ENODEV;
>         }
>
>         memcpy(dst, src, sizeof(*dst));
>
>         dispc.feat = dst;
>
>  Tomi
>

ok, looks cleaner.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-21 11:18         ` Mahapatra, Chandrabhanu
@ 2012-08-21 11:20           ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 11:20 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1867 bytes --]

On Tue, 2012-08-21 at 16:36 +0530, Mahapatra, Chandrabhanu wrote:
> On Tue, Aug 21, 2012 at 4:05 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > On Mon, 2012-08-20 at 18:53 +0530, Chandrabhanu Mahapatra wrote:
> >> 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>
> >> ---
> >>  drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
> >>  1 file changed, 76 insertions(+), 41 deletions(-)
> >>
> >> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> >> index 10566ae..f6d3d0a 100644
> >> --- a/drivers/video/omap2/dss/dss.c
> >> +++ b/drivers/video/omap2/dss/dss.c
> >> @@ -31,6 +31,7 @@
> >>  #include <linux/clk.h>
> >>  #include <linux/platform_device.h>
> >>  #include <linux/pm_runtime.h>
> >> +#include <linux/gfp.h>
> >>
> >>  #include <video/omapdss.h>
> >>
> >> @@ -65,6 +66,12 @@ struct dss_reg {
> >>  static int dss_runtime_get(void);
> >>  static void dss_runtime_put(void);
> >>
> >> +struct dss_features {
> >> +     u16 fck_div_max;
> >> +     int dss_fck_multiplier;
> >> +     char *clk_name;
> >
> > const char *
> >
> >  Tomi
> >
> 
> All the values are const. So we have a const pointer dss.feat to hold
> this structure. Is a separate
> const char *clk_name required?

Yes, the values are const, so the pointer itself is const. However, the
chars where the pointer points are not const. So:

feat.clk_name = 1234; // this is rejected by the compiler
feat.clk_name[0] = 0; // this would be accepted

 Tomi




[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-21 11:20           ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-21 11:20 UTC (permalink / raw)
  To: Mahapatra, Chandrabhanu; +Cc: linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 1867 bytes --]

On Tue, 2012-08-21 at 16:36 +0530, Mahapatra, Chandrabhanu wrote:
> On Tue, Aug 21, 2012 at 4:05 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > On Mon, 2012-08-20 at 18:53 +0530, Chandrabhanu Mahapatra wrote:
> >> 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>
> >> ---
> >>  drivers/video/omap2/dss/dss.c |  117 ++++++++++++++++++++++++++---------------
> >>  1 file changed, 76 insertions(+), 41 deletions(-)
> >>
> >> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> >> index 10566ae..f6d3d0a 100644
> >> --- a/drivers/video/omap2/dss/dss.c
> >> +++ b/drivers/video/omap2/dss/dss.c
> >> @@ -31,6 +31,7 @@
> >>  #include <linux/clk.h>
> >>  #include <linux/platform_device.h>
> >>  #include <linux/pm_runtime.h>
> >> +#include <linux/gfp.h>
> >>
> >>  #include <video/omapdss.h>
> >>
> >> @@ -65,6 +66,12 @@ struct dss_reg {
> >>  static int dss_runtime_get(void);
> >>  static void dss_runtime_put(void);
> >>
> >> +struct dss_features {
> >> +     u16 fck_div_max;
> >> +     int dss_fck_multiplier;
> >> +     char *clk_name;
> >
> > const char *
> >
> >  Tomi
> >
> 
> All the values are const. So we have a const pointer dss.feat to hold
> this structure. Is a separate
> const char *clk_name required?

Yes, the values are const, so the pointer itself is const. However, the
chars where the pointer points are not const. So:

feat.clk_name = 1234; // this is rejected by the compiler
feat.clk_name[0] = 0; // this would be accepted

 Tomi




[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4
@ 2012-08-21 11:25         ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-21 11:25 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: tony, paul, linux-omap, linux-fbdev

On Tue, Aug 21, 2012 at 4:02 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-20 at 18:54 +0530, Chandrabhanu Mahapatra wrote:
>> This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
>> prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
>> VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
>> of a device for VENC on OMAP4.
>>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  arch/arm/mach-omap2/display.c |    1 -
>>  1 file changed, 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
>> index af1ed7d..ee40739 100644
>> --- a/arch/arm/mach-omap2/display.c
>> +++ b/arch/arm/mach-omap2/display.c
>> @@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
>>       { "dss_core", "omapdss_dss", -1 },
>>       { "dss_dispc", "omapdss_dispc", -1 },
>>       { "dss_rfbi", "omapdss_rfbi", -1 },
>> -     { "dss_venc", "omapdss_venc", -1 },
>>       { "dss_dsi1", "omapdss_dsi", 0 },
>>       { "dss_dsi2", "omapdss_dsi", 1 },
>>       { "dss_hdmi", "omapdss_hdmi", -1 },
>
> You need to reorder this and the previous patch. If you first remove the
> workaround from the previous patch, the kernel will crash if after that
> patch. So this one should be before the previous patch.
>
>  Tomi
>

Ok.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
@ 2012-08-21 11:32         ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 146+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-21 11:32 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev

On Tue, Aug 21, 2012 at 4:01 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2012-08-20 at 18:52 +0530, Chandrabhanu Mahapatra wrote:
>> All the cpu_is checks have been moved to dispc_init_features function providing
>> a much more generic and cleaner interface. The OMAP version and revision
>> specific functions and data are initialized by dispc_features structure which is
>> local to dispc.c.
>>
>> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
>> ---
>>  drivers/video/omap2/dss/dispc.c |  433 +++++++++++++++++++++++++--------------
>>  1 file changed, 278 insertions(+), 155 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
>> index ff52702..3fad33a 100644
>> --- a/drivers/video/omap2/dss/dispc.c
>> +++ b/drivers/video/omap2/dss/dispc.c
>> @@ -81,6 +81,23 @@ struct dispc_irq_stats {
>>       unsigned irqs[32];
>>  };
>>
>> +struct dispc_features {
>> +     int hp_max;
>> +     int vp_max;
>> +     int sw_max;
>> +     int sw_start;
>> +     int fp_start;
>> +     int bp_start;
>
> Here you could use a bit smaller datatype. u16 should probably be more
> than enough.
>

After looking at the values that these variables take I think hp_max,
vp_max and sw_max can be u16 and the rest three sw_start, fp_start and
bp_start can be u8.

>> +static int __init dispc_init_features(struct device *dev)
>> +{
>> +     struct dispc_features *feat = devm_kzalloc(dev, sizeof(*feat),
>> +                                                             GFP_KERNEL);
>> +     if (!feat) {
>> +             dev_err(dev, "Failed to allocate DISPC Features\n");
>> +             return -ENOMEM;
>> +     }
>> +
>> +     if (cpu_is_omap24xx()) {
>> +             memcpy(feat, &omap24xx_dispc_feats, sizeof(*feat));
>> +     } else if (cpu_is_omap34xx()) {
>> +             if (omap_rev() < OMAP3430_REV_ES3_0)
>> +                     memcpy(feat, &omap34xx_rev1_0_dispc_feats,
>> +                                                     sizeof(*feat));
>> +             else
>> +                     memcpy(feat, &omap34xx_rev3_0_dispc_feats,
>> +                                                     sizeof(*feat));
>> +     } else if (cpu_is_omap44xx()) {
>> +             memcpy(feat, &omap44xx_dispc_feats, sizeof(*feat));
>> +     } else {
>> +             return -ENODEV;
>> +     }
>> +
>> +     dispc.feat = feat;
>> +
>> +     return 0;
>> +}
>
> This becomes much cleaner with something like the following (same could
> be used in dss.c also):
>
>         const struct dispc_features *src;
>         struct dispc_features *dst;
>
>         dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
>         if (!dsst) {
>                 dev_err(dev, "Failed to allocate DISPC Features\n");
>                 return -ENOMEM;
>         }
>
>         if (cpu_is_omap24xx()) {
>                 src = &omap24xx_dispc_feats;
>         } else if (cpu_is_omap34xx()) {
>                 if (omap_rev() < OMAP3430_REV_ES3_0)
>                         src = &omap34xx_rev1_0_dispc_feats;
>                 else
>                         src = &omap34xx_rev3_0_dispc_feats;
>         } else if (cpu_is_omap44xx()) {
>                 src = &omap44xx_dispc_feats;
>         } else {
>                 return -ENODEV;
>         }
>
>         memcpy(dst, src, sizeof(*dst));
>
>         dispc.feat = dst;
>
>  Tomi
>

ok, looks cleaner.

-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
  (?)
@ 2012-08-22  6:36     ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:36 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, linux-arm-kernel, Chandrabhanu Mahapatra

Hi everyone,
this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
more generic.

The 1st patch cleans up cpu_is checks from DISPC code.
The 2nd patch removes unused functions from DSS code.
The 3rd patch cleans up cpu_is checks from DSS code.
The 4th patch disables VENC support on OMAP4.
The 5th patch removes cpu_is checks from VENC code.
The 6th patch removes cpu_is checks from DPI code and replaces it with a
dss feature.

Changes from V1 to V5 series:
 1st patch :
	* moved dispc_ops structure definitions from dss_features.c to dispc.c
	  and renamed it to dispc_features
	* moved dispc_features definitions close to dispc_init_features() thereby
	  eliminating various functions declarations from top of dispc.c
	* used __initconst before dispc_features definitions and __init before
	  dispc_init_features()
	* removed definitions of _dispc_lcd_timings_ok_24xx,
	  _dispc_lcd_timings_ok_44xx, _dispc_mgr_set_lcd_timings_hv_24xx and
	  _dispc_mgr_set_lcd_timings_hv_44xx replacing them with appropiate variables
	* renamed various dispc_features structures to give consistent naming

 3rd patch :
	* moved dss_ops structure definitions from dss_features.c to dss.c and
	  renamed it to dss_features
	* removed all functions from dss_features structure and replaced them with
	  appropiate variables
	* used __initconst before dss_features definitions and __init before 
	  dss_init_features()
	* renamed various dss_features structures to give consistent naming
	* renamed factor variable of dss_features structure to dss_fck_multiplier

Changes from V5 to V6 series:
	* The "ARM: OMAP: Disable venc for OMAP4" patch has been placed before
	  "OMAPDSS: VENC: Remove cpu_is_xxxx checks" patch
 1st patch:
	* The dispc_init_features() implementation has been corrected
	* The variables types of variables in dispc_features has been changed
	  to u8 and u16 as found appropiate
 2nd patch:
	* The dss_init_features() implementation has been corrected
	* In dss_features struct char * has been changed to const char * and
	  int replaced with u8

All your comments and suggestions are welcome.

Refenence Tree:
git@gitorious.org:~chandrabhanu/linux-omap-dss2/chandrabhanus-linux.git dss_cleanup

Regards,
Chandrabhanu

Chandrabhanu Mahapatra (6):
  OMAPDSS: DISPC: Cleanup cpu_is_xxxx checks
  OMAPDSS: DSS: Remove redundant functions
  OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  ARM: OMAP: Disable venc for OMAP4
  OMAPDSS: VENC: Remove cpu_is_xxxx checks
  OMAPDSS: DPI: Remove cpu_is_xxxx checks

 arch/arm/mach-omap2/display.c          |    1 -
 drivers/video/omap2/dss/dispc.c        |  434 ++++++++++++++++++++------------
 drivers/video/omap2/dss/dpi.c          |   12 +-
 drivers/video/omap2/dss/dss.c          |  165 ++++++------
 drivers/video/omap2/dss/dss.h          |    2 -
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/venc.c         |   11 -
 8 files changed, 367 insertions(+), 260 deletions(-)

-- 
1.7.10


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-22  6:36     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi everyone,
this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
more generic.

The 1st patch cleans up cpu_is checks from DISPC code.
The 2nd patch removes unused functions from DSS code.
The 3rd patch cleans up cpu_is checks from DSS code.
The 4th patch disables VENC support on OMAP4.
The 5th patch removes cpu_is checks from VENC code.
The 6th patch removes cpu_is checks from DPI code and replaces it with a
dss feature.

Changes from V1 to V5 series:
 1st patch :
	* moved dispc_ops structure definitions from dss_features.c to dispc.c
	  and renamed it to dispc_features
	* moved dispc_features definitions close to dispc_init_features() thereby
	  eliminating various functions declarations from top of dispc.c
	* used __initconst before dispc_features definitions and __init before
	  dispc_init_features()
	* removed definitions of _dispc_lcd_timings_ok_24xx,
	  _dispc_lcd_timings_ok_44xx, _dispc_mgr_set_lcd_timings_hv_24xx and
	  _dispc_mgr_set_lcd_timings_hv_44xx replacing them with appropiate variables
	* renamed various dispc_features structures to give consistent naming

 3rd patch :
	* moved dss_ops structure definitions from dss_features.c to dss.c and
	  renamed it to dss_features
	* removed all functions from dss_features structure and replaced them with
	  appropiate variables
	* used __initconst before dss_features definitions and __init before 
	  dss_init_features()
	* renamed various dss_features structures to give consistent naming
	* renamed factor variable of dss_features structure to dss_fck_multiplier

Changes from V5 to V6 series:
	* The "ARM: OMAP: Disable venc for OMAP4" patch has been placed before
	  "OMAPDSS: VENC: Remove cpu_is_xxxx checks" patch
 1st patch:
	* The dispc_init_features() implementation has been corrected
	* The variables types of variables in dispc_features has been changed
	  to u8 and u16 as found appropiate
 2nd patch:
	* The dss_init_features() implementation has been corrected
	* In dss_features struct char * has been changed to const char * and
	  int replaced with u8

All your comments and suggestions are welcome.

Refenence Tree:
git at gitorious.org:~chandrabhanu/linux-omap-dss2/chandrabhanus-linux.git dss_cleanup

Regards,
Chandrabhanu

Chandrabhanu Mahapatra (6):
  OMAPDSS: DISPC: Cleanup cpu_is_xxxx checks
  OMAPDSS: DSS: Remove redundant functions
  OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  ARM: OMAP: Disable venc for OMAP4
  OMAPDSS: VENC: Remove cpu_is_xxxx checks
  OMAPDSS: DPI: Remove cpu_is_xxxx checks

 arch/arm/mach-omap2/display.c          |    1 -
 drivers/video/omap2/dss/dispc.c        |  434 ++++++++++++++++++++------------
 drivers/video/omap2/dss/dpi.c          |   12 +-
 drivers/video/omap2/dss/dss.c          |  165 ++++++------
 drivers/video/omap2/dss/dss.h          |    2 -
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/venc.c         |   11 -
 8 files changed, 367 insertions(+), 260 deletions(-)

-- 
1.7.10

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V6 1/6] OMAPDSS: DISPC: Cleanup cpu_is_xxxx checks
  2012-08-22  6:36     ` Chandrabhanu Mahapatra
@ 2012-08-22  6:49       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:37 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  434 +++++++++++++++++++++++++--------------
 1 file changed, 279 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ff52702..0de9a7e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	u8 sw_start;
+	u8 fp_start;
+	u8 bp_start;
+	u16 sw_max;
+	u16 vp_max;
+	u16 hp_max;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
 	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth =
+				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth =
-				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width == out_width && height == out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,80 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct dispc_features omap24xx_dispc_feats __initconst = {
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.sw_max			=	64,
+	.vp_max			=	255,
+	.hp_max			=	256,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.sw_max			=	64,
+	.vp_max			=	255,
+	.hp_max			=	256,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.sw_max			=	256,
+	.vp_max			=	4095,
+	.hp_max			=	4096,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap44xx_dispc_feats __initconst = {
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.sw_max			=	256,
+	.vp_max			=	4095,
+	.hp_max			=	4096,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	const struct dispc_features *src;
+	struct dispc_features *dst;
+
+	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+	if (!dst) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		src = &omap24xx_dispc_feats;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			src = &omap34xx_rev1_0_dispc_feats;
+		else
+			src = &omap34xx_rev3_0_dispc_feats;
+	} else if (cpu_is_omap44xx()) {
+		src = &omap44xx_dispc_feats;
+	} else {
+		return -ENODEV;
+	}
+
+	memcpy(dst, src, sizeof(*dst));
+	dispc.feat = dst;
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3681,6 +3801,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.pdev = pdev;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	spin_lock_init(&dispc.irq_lock);
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 2/6] OMAPDSS: DSS: Remove redundant functions
  2012-08-22  6:36     ` Chandrabhanu Mahapatra
@ 2012-08-22  6:49       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:37 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Functions dss_calc_clock_rates() and dss_get_clock_div() are removed as these
functions have become redundant and no longer used.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |   45 -----------------------------------------
 drivers/video/omap2/dss/dss.h |    2 --
 2 files changed, 47 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 92353be..e2e0fa4 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 	}
 }
 
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-		u16 fck_div_max = 16;
-
-		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));
-
-		cinfo->fck = prate / cinfo->fck_div;
-	} else {
-		if (cinfo->fck_div != 0)
-			return -EINVAL;
-		cinfo->fck = clk_get_rate(dss.dss_clk);
-	}
-
-	return 0;
-}
-
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
 	if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
 	return 0;
 }
 
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
-	cinfo->fck = clk_get_rate(dss.dss_clk);
-
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			cinfo->fck_div = prate / (cinfo->fck);
-		else
-			cinfo->fck_div = prate / (cinfo->fck / 2);
-	} else {
-		cinfo->fck_div = 0;
-	}
-
-	return 0;
-}
-
 unsigned long dss_get_dpll4_rate(void)
 {
 	if (dss.dpll4_m4_ck)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 41c00dc..d6cca82 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -296,9 +296,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  2012-08-22  6:36     ` Chandrabhanu Mahapatra
@ 2012-08-22  6:50       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  120 +++++++++++++++++++++++++++--------------
 1 file changed, 79 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index e2e0fa4..31a553a 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/gfp.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,12 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u8 fck_div_max;
+	u8 dss_fck_multiplier;
+	const char *clk_name;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +90,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +100,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap24xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct dss_features omap34xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap3630_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap44xx_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__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)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +291,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->dss_fck_multiplier, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +494,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +504,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck == dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck == fck)) {
+	if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
+		dss.cache_dss_cinfo.fck == fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +542,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max == 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->dss_fck_multiplier;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -645,22 +662,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -716,6 +722,34 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	const struct dss_features *src;
+	struct dss_features *dst;
+
+	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+	if (!dst) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		src = &omap24xx_dss_feats;
+	else if (cpu_is_omap34xx())
+		src = &omap34xx_dss_feats;
+	else if (cpu_is_omap3630())
+		src = &omap3630_dss_feats;
+	else if (cpu_is_omap44xx())
+		src = &omap44xx_dss_feats;
+	else
+		return -ENODEV;
+
+	memcpy(dst, src, sizeof(*dst));
+	dss.feat = dst;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -725,6 +759,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 
 	dss.pdev = pdev;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
 	if (!dss_mem) {
 		DSSERR("can't get IORESOURCE_MEM DSS\n");
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 4/6] ARM: OMAP: Disable venc for OMAP4
  2012-08-22  6:36     ` Chandrabhanu Mahapatra
  (?)
@ 2012-08-22  6:38       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:38 UTC (permalink / raw)
  To: tomi.valkeinen, tony, paul
  Cc: linux-omap, linux-fbdev, linux-arm-kernel, Chandrabhanu Mahapatra

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 4/6] ARM: OMAP: Disable venc for OMAP4
@ 2012-08-22  6:38       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:38 UTC (permalink / raw)
  To: linux-arm-kernel

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 5/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
  2012-08-22  6:36     ` Chandrabhanu Mahapatra
@ 2012-08-22  6:50       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

OMAP4 checks are removed from VENC to provide it a cleaner interface. These
checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
"OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
from crashing OMAP4 kernel.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/venc.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7d3eef8..4a6caf9 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -674,11 +674,6 @@ static void venc_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
-	if (cpu_is_omap44xx()) {
-		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
-		return;
-	}
-
 	if (venc_runtime_get())
 		return;
 
@@ -893,16 +888,10 @@ static struct platform_driver omap_venchw_driver = {
 
 int __init venc_init_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return 0;
-
 	return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
 }
 
 void __exit venc_uninit_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return;
-
 	platform_driver_unregister(&omap_venchw_driver);
 }
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks
  2012-08-22  6:36     ` Chandrabhanu Mahapatra
@ 2012-08-22  6:51       ` Chandrabhanu Mahapatra
  -1 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:39 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The OMAP3 checks have been removed and replaced by a dss feature
FEAT_DPI_USES_VDDS_DSI for cleaner implementation. The patches
"OMAP: DSS2: enable VDDS_DSI when using DPI" (8a2cfea8cc) by Tomi Valkeinen
<tomi.valkeinen@nokia.com> and "ARM: omap: fix oops in
drivers/video/omap2/dss/dpi.c" (4041071571) by Russell King
<rmk+kernel@arm.linux.org.uk> had introduced these checks. As it is evident
from these patches a dependency exists for some DSS pins on VDDS_DSI which is
better shown by dss feature FEAT_DPI_USES_VDDS_DSI.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dpi.c          |   12 +++++++-----
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f260343..25fb895 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -34,6 +34,7 @@
 #include <plat/cpu.h>
 
 #include "dss.h"
+#include "dss_features.h"
 
 static struct {
 	struct regulator *vdds_dsi_reg;
@@ -175,7 +176,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&dpi.lock);
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
 		r = -ENODEV;
 		goto err_no_reg;
@@ -193,7 +194,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -239,7 +240,7 @@ err_dsi_pll_init:
 err_get_dsi:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
@@ -265,7 +266,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
@@ -362,7 +363,8 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+					dpi.vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..2fe39d6 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -373,6 +373,7 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
 	FEAT_ALPHA_FIXED_ZORDER,
 	FEAT_FIFO_MERGE,
 	FEAT_OMAP3_DSI_FIFO_BUG,
+	FEAT_DPI_USES_VDDS_DSI,
 };
 
 static const enum dss_feat_id omap3630_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..26d43a4 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@ enum dss_feat_id {
 	FEAT_DSI_VC_OCP_WIDTH,
 	FEAT_DSI_REVERSE_TXCLKESC,
 	FEAT_DSI_GNQ,
+	FEAT_DPI_USES_VDDS_DSI,
 	FEAT_HDMI_CTS_SWMODE,
 	FEAT_HDMI_AUDIO_USE_MCLK,
 	FEAT_HANDLE_UV_SEPARATE,
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-22  6:36     ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi everyone,
this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
more generic.

The 1st patch cleans up cpu_is checks from DISPC code.
The 2nd patch removes unused functions from DSS code.
The 3rd patch cleans up cpu_is checks from DSS code.
The 4th patch disables VENC support on OMAP4.
The 5th patch removes cpu_is checks from VENC code.
The 6th patch removes cpu_is checks from DPI code and replaces it with a
dss feature.

Changes from V1 to V5 series:
 1st patch :
	* moved dispc_ops structure definitions from dss_features.c to dispc.c
	  and renamed it to dispc_features
	* moved dispc_features definitions close to dispc_init_features() thereby
	  eliminating various functions declarations from top of dispc.c
	* used __initconst before dispc_features definitions and __init before
	  dispc_init_features()
	* removed definitions of _dispc_lcd_timings_ok_24xx,
	  _dispc_lcd_timings_ok_44xx, _dispc_mgr_set_lcd_timings_hv_24xx and
	  _dispc_mgr_set_lcd_timings_hv_44xx replacing them with appropiate variables
	* renamed various dispc_features structures to give consistent naming

 3rd patch :
	* moved dss_ops structure definitions from dss_features.c to dss.c and
	  renamed it to dss_features
	* removed all functions from dss_features structure and replaced them with
	  appropiate variables
	* used __initconst before dss_features definitions and __init before 
	  dss_init_features()
	* renamed various dss_features structures to give consistent naming
	* renamed factor variable of dss_features structure to dss_fck_multiplier

Changes from V5 to V6 series:
	* The "ARM: OMAP: Disable venc for OMAP4" patch has been placed before
	  "OMAPDSS: VENC: Remove cpu_is_xxxx checks" patch
 1st patch:
	* The dispc_init_features() implementation has been corrected
	* The variables types of variables in dispc_features has been changed
	  to u8 and u16 as found appropiate
 2nd patch:
	* The dss_init_features() implementation has been corrected
	* In dss_features struct char * has been changed to const char * and
	  int replaced with u8

All your comments and suggestions are welcome.

Refenence Tree:
git@gitorious.org:~chandrabhanu/linux-omap-dss2/chandrabhanus-linux.git dss_cleanup

Regards,
Chandrabhanu

Chandrabhanu Mahapatra (6):
  OMAPDSS: DISPC: Cleanup cpu_is_xxxx checks
  OMAPDSS: DSS: Remove redundant functions
  OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
  ARM: OMAP: Disable venc for OMAP4
  OMAPDSS: VENC: Remove cpu_is_xxxx checks
  OMAPDSS: DPI: Remove cpu_is_xxxx checks

 arch/arm/mach-omap2/display.c          |    1 -
 drivers/video/omap2/dss/dispc.c        |  434 ++++++++++++++++++++------------
 drivers/video/omap2/dss/dpi.c          |   12 +-
 drivers/video/omap2/dss/dss.c          |  165 ++++++------
 drivers/video/omap2/dss/dss.h          |    2 -
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/venc.c         |   11 -
 8 files changed, 367 insertions(+), 260 deletions(-)

-- 
1.7.10


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V6 1/6] OMAPDSS: DISPC: Cleanup cpu_is_xxxx checks
@ 2012-08-22  6:49       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

All the cpu_is checks have been moved to dispc_init_features function providing
a much more generic and cleaner interface. The OMAP version and revision
specific functions and data are initialized by dispc_features structure which is
local to dispc.c.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  434 +++++++++++++++++++++++++--------------
 1 file changed, 279 insertions(+), 155 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ff52702..0de9a7e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -81,6 +81,23 @@ struct dispc_irq_stats {
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	u8 sw_start;
+	u8 fp_start;
+	u8 bp_start;
+	u16 sw_max;
+	u16 vp_max;
+	u16 hp_max;
+	int (*calc_scaling) (enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk);
+	unsigned long (*calc_core_clk) (enum omap_channel channel,
+		u16 width, u16 height, u16 out_width, u16 out_height);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -101,6 +118,8 @@ static struct {
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -1939,7 +1958,18 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
 		u16 height, u16 out_width, u16 out_height)
 {
 	unsigned int hf, vf;
@@ -1958,25 +1988,163 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
+	return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+		u16 height, u16 out_width, u16 out_height)
+{
+	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+				in_height, out_width, out_height);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth +			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
+			in_width, in_height, out_width, out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(channel, in_width,
+					in_height, out_width, out_height);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x = *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
 	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
+	const int maxsinglelinewidth +				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	in_width_max = dispc_core_clk_rate() /
+			DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+				out_width, out_height);
+	return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1988,12 +2156,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
-	const int maxsinglelinewidth -				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width = out_width && height = out_height)
 		return 0;
@@ -2017,118 +2182,17 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x = decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps, x_predecim,
+		y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2604,24 +2668,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2653,19 +2706,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -3671,6 +3717,80 @@ static void _omap_dispc_initial_config(void)
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct dispc_features omap24xx_dispc_feats __initconst = {
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.sw_max			=	64,
+	.vp_max			=	255,
+	.hp_max			=	256,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.sw_max			=	64,
+	.vp_max			=	255,
+	.hp_max			=	256,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.sw_max			=	256,
+	.vp_max			=	4095,
+	.hp_max			=	4096,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+};
+
+static const struct dispc_features omap44xx_dispc_feats __initconst = {
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.sw_max			=	256,
+	.vp_max			=	4095,
+	.hp_max			=	4096,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	const struct dispc_features *src;
+	struct dispc_features *dst;
+
+	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+	if (!dst) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		src = &omap24xx_dispc_feats;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			src = &omap34xx_rev1_0_dispc_feats;
+		else
+			src = &omap34xx_rev3_0_dispc_feats;
+	} else if (cpu_is_omap44xx()) {
+		src = &omap44xx_dispc_feats;
+	} else {
+		return -ENODEV;
+	}
+
+	memcpy(dst, src, sizeof(*dst));
+	dispc.feat = dst;
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3681,6 +3801,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.pdev = pdev;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	spin_lock_init(&dispc.irq_lock);
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 2/6] OMAPDSS: DSS: Remove redundant functions
@ 2012-08-22  6:49       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

Functions dss_calc_clock_rates() and dss_get_clock_div() are removed as these
functions have become redundant and no longer used.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dss.c |   45 -----------------------------------------
 drivers/video/omap2/dss/dss.h |    2 --
 2 files changed, 47 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 92353be..e2e0fa4 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 	}
 }
 
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-		u16 fck_div_max = 16;
-
-		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));
-
-		cinfo->fck = prate / cinfo->fck_div;
-	} else {
-		if (cinfo->fck_div != 0)
-			return -EINVAL;
-		cinfo->fck = clk_get_rate(dss.dss_clk);
-	}
-
-	return 0;
-}
-
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
 	if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
 	return 0;
 }
 
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
-	cinfo->fck = clk_get_rate(dss.dss_clk);
-
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			cinfo->fck_div = prate / (cinfo->fck);
-		else
-			cinfo->fck_div = prate / (cinfo->fck / 2);
-	} else {
-		cinfo->fck_div = 0;
-	}
-
-	return 0;
-}
-
 unsigned long dss_get_dpll4_rate(void)
 {
 	if (dss.dpll4_m4_ck)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 41c00dc..d6cca82 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -296,9 +296,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks
@ 2012-08-22  6:50       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:50 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

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>
---
 drivers/video/omap2/dss/dss.c |  120 +++++++++++++++++++++++++++--------------
 1 file changed, 79 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index e2e0fa4..31a553a 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/gfp.h>
 
 #include <video/omapdss.h>
 
@@ -65,6 +66,12 @@ struct dss_reg {
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u8 fck_div_max;
+	u8 dss_fck_multiplier;
+	const char *clk_name;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +90,8 @@ static struct {
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -91,6 +100,30 @@ static const char * const dss_generic_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
 };
 
+static const struct dss_features omap24xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	NULL,
+};
+
+static const struct dss_features omap34xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap3630_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll4_m4_ck",
+};
+
+static const struct dss_features omap44xx_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+};
+
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 {
 	__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)
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +291,10 @@ void dss_dump_clocks(struct seq_file *s)
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->dss_fck_multiplier, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -470,7 +494,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -480,9 +504,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck = dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate = dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck = fck)) {
+	if (req_pck = dss.cache_req_pck && prate = dss.cache_prate &&
+		dss.cache_dss_cinfo.fck = fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -519,16 +542,10 @@ retry:
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max = 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->dss_fck_multiplier;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -645,22 +662,11 @@ static int dss_get_clocks(void)
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -716,6 +722,34 @@ void dss_debug_dump_clocks(struct seq_file *s)
 }
 #endif
 
+static int __init dss_init_features(struct device *dev)
+{
+	const struct dss_features *src;
+	struct dss_features *dst;
+
+	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+	if (!dst) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		src = &omap24xx_dss_feats;
+	else if (cpu_is_omap34xx())
+		src = &omap34xx_dss_feats;
+	else if (cpu_is_omap3630())
+		src = &omap3630_dss_feats;
+	else if (cpu_is_omap44xx())
+		src = &omap44xx_dss_feats;
+	else
+		return -ENODEV;
+
+	memcpy(dst, src, sizeof(*dst));
+	dss.feat = dst;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -725,6 +759,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 
 	dss.pdev = pdev;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
 	if (!dss_mem) {
 		DSSERR("can't get IORESOURCE_MEM DSS\n");
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 4/6] ARM: OMAP: Disable venc for OMAP4
@ 2012-08-22  6:38       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
of a device for VENC on OMAP4.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 arch/arm/mach-omap2/display.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d..ee40739 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 5/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks
@ 2012-08-22  6:50       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:50 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

OMAP4 checks are removed from VENC to provide it a cleaner interface. These
checks were introduced by patches "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4
to prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> and
"OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on
OMAP4" (cc1d3e032d)  by Danny Kukawka <danny.kukawka@bisect.de> to prevent VENC
from crashing OMAP4 kernel.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/venc.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7d3eef8..4a6caf9 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -674,11 +674,6 @@ static void venc_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
-	if (cpu_is_omap44xx()) {
-		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
-		return;
-	}
-
 	if (venc_runtime_get())
 		return;
 
@@ -893,16 +888,10 @@ static struct platform_driver omap_venchw_driver = {
 
 int __init venc_init_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return 0;
-
 	return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
 }
 
 void __exit venc_uninit_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return;
-
 	platform_driver_unregister(&omap_venchw_driver);
 }
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH V6 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks
@ 2012-08-22  6:51       ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 146+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-22  6:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra

The OMAP3 checks have been removed and replaced by a dss feature
FEAT_DPI_USES_VDDS_DSI for cleaner implementation. The patches
"OMAP: DSS2: enable VDDS_DSI when using DPI" (8a2cfea8cc) by Tomi Valkeinen
<tomi.valkeinen@nokia.com> and "ARM: omap: fix oops in
drivers/video/omap2/dss/dpi.c" (4041071571) by Russell King
<rmk+kernel@arm.linux.org.uk> had introduced these checks. As it is evident
from these patches a dependency exists for some DSS pins on VDDS_DSI which is
better shown by dss feature FEAT_DPI_USES_VDDS_DSI.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
 drivers/video/omap2/dss/dpi.c          |   12 +++++++-----
 drivers/video/omap2/dss/dss_features.c |    1 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f260343..25fb895 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -34,6 +34,7 @@
 #include <plat/cpu.h>
 
 #include "dss.h"
+#include "dss_features.h"
 
 static struct {
 	struct regulator *vdds_dsi_reg;
@@ -175,7 +176,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&dpi.lock);
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
 		r = -ENODEV;
 		goto err_no_reg;
@@ -193,7 +194,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -239,7 +240,7 @@ err_dsi_pll_init:
 err_get_dsi:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
@@ -265,7 +266,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
@@ -362,7 +363,8 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg = NULL) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+					dpi.vdds_dsi_reg = NULL) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..2fe39d6 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -373,6 +373,7 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
 	FEAT_ALPHA_FIXED_ZORDER,
 	FEAT_FIFO_MERGE,
 	FEAT_OMAP3_DSI_FIFO_BUG,
+	FEAT_DPI_USES_VDDS_DSI,
 };
 
 static const enum dss_feat_id omap3630_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..26d43a4 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@ enum dss_feat_id {
 	FEAT_DSI_VC_OCP_WIDTH,
 	FEAT_DSI_REVERSE_TXCLKESC,
 	FEAT_DSI_GNQ,
+	FEAT_DPI_USES_VDDS_DSI,
 	FEAT_HDMI_CTS_SWMODE,
 	FEAT_HDMI_AUDIO_USE_MCLK,
 	FEAT_HANDLE_UV_SEPARATE,
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-22  6:36     ` Chandrabhanu Mahapatra
  (?)
@ 2012-08-22  8:44       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-22  8:44 UTC (permalink / raw)
  To: linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 620 bytes --]

On Wed, 2012-08-22 at 12:06 +0530, Chandrabhanu Mahapatra wrote:
> Hi everyone,
> this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> more generic.
> 
> The 1st patch cleans up cpu_is checks from DISPC code.
> The 2nd patch removes unused functions from DSS code.
> The 3rd patch cleans up cpu_is checks from DSS code.
> The 4th patch disables VENC support on OMAP4.
> The 5th patch removes cpu_is checks from VENC code.
> The 6th patch removes cpu_is checks from DPI code and replaces it with a
> dss feature.

Thanks, looks good. I'll apply this to omapdss tree.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-22  8:44       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-22  8:44 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra
  Cc: tony, paul, linux-omap, linux-fbdev, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 620 bytes --]

On Wed, 2012-08-22 at 12:06 +0530, Chandrabhanu Mahapatra wrote:
> Hi everyone,
> this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> more generic.
> 
> The 1st patch cleans up cpu_is checks from DISPC code.
> The 2nd patch removes unused functions from DSS code.
> The 3rd patch cleans up cpu_is checks from DSS code.
> The 4th patch disables VENC support on OMAP4.
> The 5th patch removes cpu_is checks from VENC code.
> The 6th patch removes cpu_is checks from DPI code and replaces it with a
> dss feature.

Thanks, looks good. I'll apply this to omapdss tree.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-22  8:44       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-22  8:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2012-08-22 at 12:06 +0530, Chandrabhanu Mahapatra wrote:
> Hi everyone,
> this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> more generic.
> 
> The 1st patch cleans up cpu_is checks from DISPC code.
> The 2nd patch removes unused functions from DSS code.
> The 3rd patch cleans up cpu_is checks from DSS code.
> The 4th patch disables VENC support on OMAP4.
> The 5th patch removes cpu_is checks from VENC code.
> The 6th patch removes cpu_is checks from DPI code and replaces it with a
> dss feature.

Thanks, looks good. I'll apply this to omapdss tree.

 Tomi

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120822/ac61f56d/attachment.sig>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-20 13:33   ` Chandrabhanu Mahapatra
@ 2012-08-30  0:20     ` Tony Lindgren
  -1 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-08-30  0:20 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, paul, linux-omap, linux-fbdev

* Chandrabhanu Mahapatra <cmahapatra@ti.com> [120820 06:26]:
> Hi everyone,
> this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> more generic.
> 
> The 1st patch cleans up cpu_is checks from DISPC code.
> The 2nd patch removes unused functions from DSS code.
> The 3rd patch cleans up cpu_is checks from DSS code.
> The 4th patch removes cpu_is checks from VENC code.
> The 5th patch disables VENC support on OMAP4.
> The 6th patch removes cpu_is checks from DPI code and replaces it with a
> dss feature.

Good to see this, we need this badly to avoid blocking
single zImage effort on omaps. Can you also please take
a look at the omap dss headers and make sure that
drivers/video/omap code does not do any #include <mach/*.h>
or <plat/*.h>?

The driver specific headers should be now moved to live in
include/linux/platform_data directory instead of the current
arch/arm/*omap*/include/*.

Regards,

Tony

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-30  0:20     ` Tony Lindgren
  0 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-08-30  0:20 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tomi.valkeinen, paul, linux-omap, linux-fbdev

* Chandrabhanu Mahapatra <cmahapatra@ti.com> [120820 06:26]:
> Hi everyone,
> this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> more generic.
> 
> The 1st patch cleans up cpu_is checks from DISPC code.
> The 2nd patch removes unused functions from DSS code.
> The 3rd patch cleans up cpu_is checks from DSS code.
> The 4th patch removes cpu_is checks from VENC code.
> The 5th patch disables VENC support on OMAP4.
> The 6th patch removes cpu_is checks from DPI code and replaces it with a
> dss feature.

Good to see this, we need this badly to avoid blocking
single zImage effort on omaps. Can you also please take
a look at the omap dss headers and make sure that
drivers/video/omap code does not do any #include <mach/*.h>
or <plat/*.h>?

The driver specific headers should be now moved to live in
include/linux/platform_data directory instead of the current
arch/arm/*omap*/include/*.

Regards,

Tony

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-30  0:20     ` Tony Lindgren
@ 2012-08-30  7:34       ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-30  7:34 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 4143 bytes --]

On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> * Chandrabhanu Mahapatra <cmahapatra@ti.com> [120820 06:26]:
> > Hi everyone,
> > this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> > more generic.
> > 
> > The 1st patch cleans up cpu_is checks from DISPC code.
> > The 2nd patch removes unused functions from DSS code.
> > The 3rd patch cleans up cpu_is checks from DSS code.
> > The 4th patch removes cpu_is checks from VENC code.
> > The 5th patch disables VENC support on OMAP4.
> > The 6th patch removes cpu_is checks from DPI code and replaces it with a
> > dss feature.
> 
> Good to see this, we need this badly to avoid blocking
> single zImage effort on omaps. Can you also please take

What is the issue with single zImage? How do cpu_is_ check affect it?

> a look at the omap dss headers and make sure that
> drivers/video/omap code does not do any #include <mach/*.h>
> or <plat/*.h>?
> 
> The driver specific headers should be now moved to live in
> include/linux/platform_data directory instead of the current
> arch/arm/*omap*/include/*.

I had a brief look at drivers/video/omap*. Here's a brief status. I
don't really know much about the old fb driver (drivers/video/omap) so
my comments may not be totally correct. And all fixing I do there is
done in blind, I don't have any omap1 devices.

I've left out the trivial cleanups from the list (i.e. file includes a
header that it doesn't need), there were a bunch of those. I'll make a
patch for these.


$ git grep -E "<plat|<mach" drivers/video/omap*
drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
* Needs to be moved
* lcd_ams_delta uses also omap_write/read

drivers/video/omap/lcd_inn1510.c:#include <plat/fpga.h>
* No idea about this. Who wants to convert the fpga support? =)

drivers/video/omap/lcd_mipid.c:#include <plat/lcd_mipid.h>
* Needs to be moved

drivers/video/omap/lcd_osk.c:#include <plat/mux.h>
* Uses omap_cfg_reg(PWL). I don't know what this is...
* lcd_osk.c uses omap_write/read

drivers/video/omap/lcdc.c:#include <mach/lcdc.h>
* Needs to be moved

drivers/video/omap/lcdc.c:#include <plat/dma.h>
* Uses arch/arm/mach-omap1/lcd_dma.c. Any idea about this? Will DMA
engine support OMAP1's LCD DMA?

drivers/video/omap/omapfb_main.c:#include <plat/dma.h>
* Uses DMA API to set DMA priority

drivers/video/omap/sossi.c:#include <plat/dma.h>
* Uses arch/arm/mach-omap1/lcd_dma.c

drivers/video/omap2/dss/dss.c:#include <plat/cpu.h>
* Uses cpu_is_* to find out the DSS version. dispc.c also uses cpu_is_*
functions, but doesn't include plat/cpu.h. I know cpu_is_* checks should
be removed, but is there some other file to include for the time being
than plat/cpu.h?

drivers/video/omap2/dss/dss_features.c:#include <plat/cpu.h>
* Uses cpu_is_* to find out the DSS version

drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vrfb.h>
drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vrfb.h>
drivers/video/omap2/omapfb/omapfb-sysfs.c:#include <plat/vrfb.h>
drivers/video/omap2/vram.c:#include <plat/vram.h>
drivers/video/omap2/vram.c:#include <plat/dma.h>
drivers/video/omap2/vrfb.c:#include <plat/vrfb.h>
drivers/video/omap2/vrfb.c:#include <plat/sdrc.h>

Of these, I'm not sure how to handle.

Grep shows that vram.c is only used by (the newer) omapfb, so it could
be considered a part of that driver. It still needs to be built-in, as
it needs to reserve memory early in the boot process (done with a call
from arch/arm/plat-omap/common.c).

Also board files can use a func call to define the amount of memory to
allocate, but only rx51 seems to do this in the mainline.

Anyway, I believe vram.c is going away when we start to use CMA.


As for vrfb... I'm not really sure where it belongs. It is used by the
newer omapfb and OMAP V4L2 driver. VRFB is a part of the OMAP's memory
controller, so I'm not sure if it's really a normal driver.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-30  7:34       ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-30  7:34 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 4143 bytes --]

On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> * Chandrabhanu Mahapatra <cmahapatra@ti.com> [120820 06:26]:
> > Hi everyone,
> > this patch series aims at cleaning up of DSS of cpu_is checks thereby making it
> > more generic.
> > 
> > The 1st patch cleans up cpu_is checks from DISPC code.
> > The 2nd patch removes unused functions from DSS code.
> > The 3rd patch cleans up cpu_is checks from DSS code.
> > The 4th patch removes cpu_is checks from VENC code.
> > The 5th patch disables VENC support on OMAP4.
> > The 6th patch removes cpu_is checks from DPI code and replaces it with a
> > dss feature.
> 
> Good to see this, we need this badly to avoid blocking
> single zImage effort on omaps. Can you also please take

What is the issue with single zImage? How do cpu_is_ check affect it?

> a look at the omap dss headers and make sure that
> drivers/video/omap code does not do any #include <mach/*.h>
> or <plat/*.h>?
> 
> The driver specific headers should be now moved to live in
> include/linux/platform_data directory instead of the current
> arch/arm/*omap*/include/*.

I had a brief look at drivers/video/omap*. Here's a brief status. I
don't really know much about the old fb driver (drivers/video/omap) so
my comments may not be totally correct. And all fixing I do there is
done in blind, I don't have any omap1 devices.

I've left out the trivial cleanups from the list (i.e. file includes a
header that it doesn't need), there were a bunch of those. I'll make a
patch for these.


$ git grep -E "<plat|<mach" drivers/video/omap*
drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
* Needs to be moved
* lcd_ams_delta uses also omap_write/read

drivers/video/omap/lcd_inn1510.c:#include <plat/fpga.h>
* No idea about this. Who wants to convert the fpga support? =)

drivers/video/omap/lcd_mipid.c:#include <plat/lcd_mipid.h>
* Needs to be moved

drivers/video/omap/lcd_osk.c:#include <plat/mux.h>
* Uses omap_cfg_reg(PWL). I don't know what this is...
* lcd_osk.c uses omap_write/read

drivers/video/omap/lcdc.c:#include <mach/lcdc.h>
* Needs to be moved

drivers/video/omap/lcdc.c:#include <plat/dma.h>
* Uses arch/arm/mach-omap1/lcd_dma.c. Any idea about this? Will DMA
engine support OMAP1's LCD DMA?

drivers/video/omap/omapfb_main.c:#include <plat/dma.h>
* Uses DMA API to set DMA priority

drivers/video/omap/sossi.c:#include <plat/dma.h>
* Uses arch/arm/mach-omap1/lcd_dma.c

drivers/video/omap2/dss/dss.c:#include <plat/cpu.h>
* Uses cpu_is_* to find out the DSS version. dispc.c also uses cpu_is_*
functions, but doesn't include plat/cpu.h. I know cpu_is_* checks should
be removed, but is there some other file to include for the time being
than plat/cpu.h?

drivers/video/omap2/dss/dss_features.c:#include <plat/cpu.h>
* Uses cpu_is_* to find out the DSS version

drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vrfb.h>
drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vrfb.h>
drivers/video/omap2/omapfb/omapfb-sysfs.c:#include <plat/vrfb.h>
drivers/video/omap2/vram.c:#include <plat/vram.h>
drivers/video/omap2/vram.c:#include <plat/dma.h>
drivers/video/omap2/vrfb.c:#include <plat/vrfb.h>
drivers/video/omap2/vrfb.c:#include <plat/sdrc.h>

Of these, I'm not sure how to handle.

Grep shows that vram.c is only used by (the newer) omapfb, so it could
be considered a part of that driver. It still needs to be built-in, as
it needs to reserve memory early in the boot process (done with a call
from arch/arm/plat-omap/common.c).

Also board files can use a func call to define the amount of memory to
allocate, but only rx51 seems to do this in the mainline.

Anyway, I believe vram.c is going away when we start to use CMA.


As for vrfb... I'm not really sure where it belongs. It is used by the
newer omapfb and OMAP V4L2 driver. VRFB is a part of the OMAP's memory
controller, so I'm not sure if it's really a normal driver.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-30  7:34       ` Tomi Valkeinen
@ 2012-08-30 17:19         ` Tony Lindgren
  -1 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-08-30 17:19 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

Hi,

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120830 00:35]:
> On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> > 
> > Good to see this, we need this badly to avoid blocking
> > single zImage effort on omaps. Can you also please take
> 
> What is the issue with single zImage? How do cpu_is_ check affect it?

The usage for that should only be limited to arch/arm/mach-omap2
so we can make cpu.h local as we can't include mach and plat
header files from the drivers with single zImage.
 
> I had a brief look at drivers/video/omap*. Here's a brief status. I
> don't really know much about the old fb driver (drivers/video/omap) so
> my comments may not be totally correct. And all fixing I do there is
> done in blind, I don't have any omap1 devices.
> 
> I've left out the trivial cleanups from the list (i.e. file includes a
> header that it doesn't need), there were a bunch of those. I'll make a
> patch for these.
> 
> 
> $ git grep -E "<plat|<mach" drivers/video/omap*
> drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
> * Needs to be moved

Yes, that should be either mach/board-ams-delta.h, or separate driver
specific headers in include/linux/platform_data. For omap1 we are not
planning common zImage support, so let's just make sure we're not
breaking anything there as people are still using it.

> * lcd_ams_delta uses also omap_write/read

Limiting omap_write/read to omap1 is OK for now, unless the fix
is trivial to do with ioremap + readw/writew.
 
> drivers/video/omap/lcd_inn1510.c:#include <plat/fpga.h>
> * No idea about this. Who wants to convert the fpga support? =)

I'll move it to mach/fpga.h as it's omap1 specifc.
 
> drivers/video/omap/lcd_mipid.c:#include <plat/lcd_mipid.h>
> * Needs to be moved
> 
> drivers/video/omap/lcd_osk.c:#include <plat/mux.h>
> * Uses omap_cfg_reg(PWL). I don't know what this is...

I'll move plat/mux.h into mach for omap1. For omap2+, we have
a local mux.h and are moving to use device tree based pinctrl-single
driver.

> * lcd_osk.c uses omap_write/read
> 
> drivers/video/omap/lcdc.c:#include <mach/lcdc.h>
> * Needs to be moved

This you can move to platform_data or mach for omap1?
 
> drivers/video/omap/lcdc.c:#include <plat/dma.h>
> * Uses arch/arm/mach-omap1/lcd_dma.c. Any idea about this? Will DMA
> engine support OMAP1's LCD DMA?

I think it should eventually as it can detect the device and could
automatically call those functions. Not sure if all options for
configuring it are available yet in dma engine.
 
> drivers/video/omap/omapfb_main.c:#include <plat/dma.h>
> * Uses DMA API to set DMA priority
> 
> drivers/video/omap/sossi.c:#include <plat/dma.h>
> * Uses arch/arm/mach-omap1/lcd_dma.c
> 
> drivers/video/omap2/dss/dss.c:#include <plat/cpu.h>
> * Uses cpu_is_* to find out the DSS version. dispc.c also uses cpu_is_*
> functions, but doesn't include plat/cpu.h. I know cpu_is_* checks should
> be removed, but is there some other file to include for the time being
> than plat/cpu.h?

We could make it mach/cpu.h for omap1, but ideally we would just
pass DSS_VERSION_XYZ type flag in platform data on omap1.
 
> drivers/video/omap2/dss/dss_features.c:#include <plat/cpu.h>
> * Uses cpu_is_* to find out the DSS version

Here too.
 
> drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vrfb.h>
> drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
> drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
> drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vrfb.h>
> drivers/video/omap2/omapfb/omapfb-sysfs.c:#include <plat/vrfb.h>
> drivers/video/omap2/vram.c:#include <plat/vram.h>
> drivers/video/omap2/vram.c:#include <plat/dma.h>
> drivers/video/omap2/vrfb.c:#include <plat/vrfb.h>
> drivers/video/omap2/vrfb.c:#include <plat/sdrc.h>
> 
> Of these, I'm not sure how to handle.

These should eventually be in platform_data as driver specific headers.
 
> Grep shows that vram.c is only used by (the newer) omapfb, so it could
> be considered a part of that driver. It still needs to be built-in, as
> it needs to reserve memory early in the boot process (done with a call
> from arch/arm/plat-omap/common.c).

Hmm it sounds like omap_vram_reserve_sdram_memblock() should be in
plat-omap and just pass the pointer for later use for vram.c.
 
> Also board files can use a func call to define the amount of memory to
> allocate, but only rx51 seems to do this in the mainline.
> 
> Anyway, I believe vram.c is going away when we start to use CMA.

OK cool. 
 
> As for vrfb... I'm not really sure where it belongs. It is used by the
> newer omapfb and OMAP V4L2 driver. VRFB is a part of the OMAP's memory
> controller, so I'm not sure if it's really a normal driver.

Maybe just split it to platform code for the memblock stuff and pass
the necessary information to the driver in platform_data?

Regards,

Tony


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-30 17:19         ` Tony Lindgren
  0 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-08-30 17:19 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

Hi,

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120830 00:35]:
> On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> > 
> > Good to see this, we need this badly to avoid blocking
> > single zImage effort on omaps. Can you also please take
> 
> What is the issue with single zImage? How do cpu_is_ check affect it?

The usage for that should only be limited to arch/arm/mach-omap2
so we can make cpu.h local as we can't include mach and plat
header files from the drivers with single zImage.
 
> I had a brief look at drivers/video/omap*. Here's a brief status. I
> don't really know much about the old fb driver (drivers/video/omap) so
> my comments may not be totally correct. And all fixing I do there is
> done in blind, I don't have any omap1 devices.
> 
> I've left out the trivial cleanups from the list (i.e. file includes a
> header that it doesn't need), there were a bunch of those. I'll make a
> patch for these.
> 
> 
> $ git grep -E "<plat|<mach" drivers/video/omap*
> drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
> * Needs to be moved

Yes, that should be either mach/board-ams-delta.h, or separate driver
specific headers in include/linux/platform_data. For omap1 we are not
planning common zImage support, so let's just make sure we're not
breaking anything there as people are still using it.

> * lcd_ams_delta uses also omap_write/read

Limiting omap_write/read to omap1 is OK for now, unless the fix
is trivial to do with ioremap + readw/writew.
 
> drivers/video/omap/lcd_inn1510.c:#include <plat/fpga.h>
> * No idea about this. Who wants to convert the fpga support? =)

I'll move it to mach/fpga.h as it's omap1 specifc.
 
> drivers/video/omap/lcd_mipid.c:#include <plat/lcd_mipid.h>
> * Needs to be moved
> 
> drivers/video/omap/lcd_osk.c:#include <plat/mux.h>
> * Uses omap_cfg_reg(PWL). I don't know what this is...

I'll move plat/mux.h into mach for omap1. For omap2+, we have
a local mux.h and are moving to use device tree based pinctrl-single
driver.

> * lcd_osk.c uses omap_write/read
> 
> drivers/video/omap/lcdc.c:#include <mach/lcdc.h>
> * Needs to be moved

This you can move to platform_data or mach for omap1?
 
> drivers/video/omap/lcdc.c:#include <plat/dma.h>
> * Uses arch/arm/mach-omap1/lcd_dma.c. Any idea about this? Will DMA
> engine support OMAP1's LCD DMA?

I think it should eventually as it can detect the device and could
automatically call those functions. Not sure if all options for
configuring it are available yet in dma engine.
 
> drivers/video/omap/omapfb_main.c:#include <plat/dma.h>
> * Uses DMA API to set DMA priority
> 
> drivers/video/omap/sossi.c:#include <plat/dma.h>
> * Uses arch/arm/mach-omap1/lcd_dma.c
> 
> drivers/video/omap2/dss/dss.c:#include <plat/cpu.h>
> * Uses cpu_is_* to find out the DSS version. dispc.c also uses cpu_is_*
> functions, but doesn't include plat/cpu.h. I know cpu_is_* checks should
> be removed, but is there some other file to include for the time being
> than plat/cpu.h?

We could make it mach/cpu.h for omap1, but ideally we would just
pass DSS_VERSION_XYZ type flag in platform data on omap1.
 
> drivers/video/omap2/dss/dss_features.c:#include <plat/cpu.h>
> * Uses cpu_is_* to find out the DSS version

Here too.
 
> drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vrfb.h>
> drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
> drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
> drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vrfb.h>
> drivers/video/omap2/omapfb/omapfb-sysfs.c:#include <plat/vrfb.h>
> drivers/video/omap2/vram.c:#include <plat/vram.h>
> drivers/video/omap2/vram.c:#include <plat/dma.h>
> drivers/video/omap2/vrfb.c:#include <plat/vrfb.h>
> drivers/video/omap2/vrfb.c:#include <plat/sdrc.h>
> 
> Of these, I'm not sure how to handle.

These should eventually be in platform_data as driver specific headers.
 
> Grep shows that vram.c is only used by (the newer) omapfb, so it could
> be considered a part of that driver. It still needs to be built-in, as
> it needs to reserve memory early in the boot process (done with a call
> from arch/arm/plat-omap/common.c).

Hmm it sounds like omap_vram_reserve_sdram_memblock() should be in
plat-omap and just pass the pointer for later use for vram.c.
 
> Also board files can use a func call to define the amount of memory to
> allocate, but only rx51 seems to do this in the mainline.
> 
> Anyway, I believe vram.c is going away when we start to use CMA.

OK cool. 
 
> As for vrfb... I'm not really sure where it belongs. It is used by the
> newer omapfb and OMAP V4L2 driver. VRFB is a part of the OMAP's memory
> controller, so I'm not sure if it's really a normal driver.

Maybe just split it to platform code for the memblock stuff and pass
the necessary information to the driver in platform_data?

Regards,

Tony


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-30 17:19         ` Tony Lindgren
@ 2012-08-31 11:23           ` Tomi Valkeinen
  -1 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 11:23 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 3923 bytes --]

On Thu, 2012-08-30 at 10:19 -0700, Tony Lindgren wrote:
> Hi,
> 
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [120830 00:35]:
> > On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> > > 
> > > Good to see this, we need this badly to avoid blocking
> > > single zImage effort on omaps. Can you also please take
> > 
> > What is the issue with single zImage? How do cpu_is_ check affect it?
> 
> The usage for that should only be limited to arch/arm/mach-omap2
> so we can make cpu.h local as we can't include mach and plat
> header files from the drivers with single zImage.

Ok.

> > $ git grep -E "<plat|<mach" drivers/video/omap*
> > drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
> > * Needs to be moved
> 
> Yes, that should be either mach/board-ams-delta.h, or separate driver
> specific headers in include/linux/platform_data. For omap1 we are not
> planning common zImage support, so let's just make sure we're not
> breaking anything there as people are still using it.

Hmm, so did I understand right, for omap1 stuff we can still include
from arch/arm/mach-omap1/include/mach?

If so, that makes things easier. I can manage the omap2+ stuff fine, but
I have no experience with omap1, nor do I have any omap1 devices. So I'd
rather keep the omap1 code as it is, in fear that I'd just break it
totally, and I'd rather spend my time on omap2+ code.

> > drivers/video/omap2/dss/dss.c:#include <plat/cpu.h>
> > * Uses cpu_is_* to find out the DSS version. dispc.c also uses cpu_is_*
> > functions, but doesn't include plat/cpu.h. I know cpu_is_* checks should
> > be removed, but is there some other file to include for the time being
> > than plat/cpu.h?
> 
> We could make it mach/cpu.h for omap1, but ideally we would just
> pass DSS_VERSION_XYZ type flag in platform data on omap1.

Ok. The omap1 fb driver seems to contain a few cpu_is_omap15xx() checks,
nothing else.

> > drivers/video/omap2/dss/dss_features.c:#include <plat/cpu.h>
> > * Uses cpu_is_* to find out the DSS version
> 
> Here too.

Yep, for omap2+ I'll create a version ID that we'll pass via plat data.
 
> > drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vrfb.h>
> > drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
> > drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
> > drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vrfb.h>
> > drivers/video/omap2/omapfb/omapfb-sysfs.c:#include <plat/vrfb.h>
> > drivers/video/omap2/vram.c:#include <plat/vram.h>
> > drivers/video/omap2/vram.c:#include <plat/dma.h>
> > drivers/video/omap2/vrfb.c:#include <plat/vrfb.h>
> > drivers/video/omap2/vrfb.c:#include <plat/sdrc.h>
> > 
> > Of these, I'm not sure how to handle.
> 
> These should eventually be in platform_data as driver specific headers.
>  
> > Grep shows that vram.c is only used by (the newer) omapfb, so it could
> > be considered a part of that driver. It still needs to be built-in, as
> > it needs to reserve memory early in the boot process (done with a call
> > from arch/arm/plat-omap/common.c).
> 
> Hmm it sounds like omap_vram_reserve_sdram_memblock() should be in
> plat-omap and just pass the pointer for later use for vram.c.
>  
> > Also board files can use a func call to define the amount of memory to
> > allocate, but only rx51 seems to do this in the mainline.
> > 
> > Anyway, I believe vram.c is going away when we start to use CMA.
> 
> OK cool. 
>  
> > As for vrfb... I'm not really sure where it belongs. It is used by the
> > newer omapfb and OMAP V4L2 driver. VRFB is a part of the OMAP's memory
> > controller, so I'm not sure if it's really a normal driver.
> 
> Maybe just split it to platform code for the memblock stuff and pass
> the necessary information to the driver in platform_data?

I'll try to figure out something for vrfb.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-08-31 11:23           ` Tomi Valkeinen
  0 siblings, 0 replies; 146+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 11:23 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 3923 bytes --]

On Thu, 2012-08-30 at 10:19 -0700, Tony Lindgren wrote:
> Hi,
> 
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [120830 00:35]:
> > On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> > > 
> > > Good to see this, we need this badly to avoid blocking
> > > single zImage effort on omaps. Can you also please take
> > 
> > What is the issue with single zImage? How do cpu_is_ check affect it?
> 
> The usage for that should only be limited to arch/arm/mach-omap2
> so we can make cpu.h local as we can't include mach and plat
> header files from the drivers with single zImage.

Ok.

> > $ git grep -E "<plat|<mach" drivers/video/omap*
> > drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
> > * Needs to be moved
> 
> Yes, that should be either mach/board-ams-delta.h, or separate driver
> specific headers in include/linux/platform_data. For omap1 we are not
> planning common zImage support, so let's just make sure we're not
> breaking anything there as people are still using it.

Hmm, so did I understand right, for omap1 stuff we can still include
from arch/arm/mach-omap1/include/mach?

If so, that makes things easier. I can manage the omap2+ stuff fine, but
I have no experience with omap1, nor do I have any omap1 devices. So I'd
rather keep the omap1 code as it is, in fear that I'd just break it
totally, and I'd rather spend my time on omap2+ code.

> > drivers/video/omap2/dss/dss.c:#include <plat/cpu.h>
> > * Uses cpu_is_* to find out the DSS version. dispc.c also uses cpu_is_*
> > functions, but doesn't include plat/cpu.h. I know cpu_is_* checks should
> > be removed, but is there some other file to include for the time being
> > than plat/cpu.h?
> 
> We could make it mach/cpu.h for omap1, but ideally we would just
> pass DSS_VERSION_XYZ type flag in platform data on omap1.

Ok. The omap1 fb driver seems to contain a few cpu_is_omap15xx() checks,
nothing else.

> > drivers/video/omap2/dss/dss_features.c:#include <plat/cpu.h>
> > * Uses cpu_is_* to find out the DSS version
> 
> Here too.

Yep, for omap2+ I'll create a version ID that we'll pass via plat data.
 
> > drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vrfb.h>
> > drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
> > drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
> > drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vrfb.h>
> > drivers/video/omap2/omapfb/omapfb-sysfs.c:#include <plat/vrfb.h>
> > drivers/video/omap2/vram.c:#include <plat/vram.h>
> > drivers/video/omap2/vram.c:#include <plat/dma.h>
> > drivers/video/omap2/vrfb.c:#include <plat/vrfb.h>
> > drivers/video/omap2/vrfb.c:#include <plat/sdrc.h>
> > 
> > Of these, I'm not sure how to handle.
> 
> These should eventually be in platform_data as driver specific headers.
>  
> > Grep shows that vram.c is only used by (the newer) omapfb, so it could
> > be considered a part of that driver. It still needs to be built-in, as
> > it needs to reserve memory early in the boot process (done with a call
> > from arch/arm/plat-omap/common.c).
> 
> Hmm it sounds like omap_vram_reserve_sdram_memblock() should be in
> plat-omap and just pass the pointer for later use for vram.c.
>  
> > Also board files can use a func call to define the amount of memory to
> > allocate, but only rx51 seems to do this in the mainline.
> > 
> > Anyway, I believe vram.c is going away when we start to use CMA.
> 
> OK cool. 
>  
> > As for vrfb... I'm not really sure where it belongs. It is used by the
> > newer omapfb and OMAP V4L2 driver. VRFB is a part of the OMAP's memory
> > controller, so I'm not sure if it's really a normal driver.
> 
> Maybe just split it to platform code for the memblock stuff and pass
> the necessary information to the driver in platform_data?

I'll try to figure out something for vrfb.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
  2012-08-31 11:23           ` Tomi Valkeinen
@ 2012-09-06 20:08             ` Tony Lindgren
  -1 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-09-06 20:08 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120831 04:24]:
> On Thu, 2012-08-30 at 10:19 -0700, Tony Lindgren wrote:
> > Hi,
> > 
> > * Tomi Valkeinen <tomi.valkeinen@ti.com> [120830 00:35]:
> > > On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> > > > 
> > > > Good to see this, we need this badly to avoid blocking
> > > > single zImage effort on omaps. Can you also please take
> > > 
> > > What is the issue with single zImage? How do cpu_is_ check affect it?
> > 
> > The usage for that should only be limited to arch/arm/mach-omap2
> > so we can make cpu.h local as we can't include mach and plat
> > header files from the drivers with single zImage.
> 
> Ok.
> 
> > > $ git grep -E "<plat|<mach" drivers/video/omap*
> > > drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
> > > * Needs to be moved
> > 
> > Yes, that should be either mach/board-ams-delta.h, or separate driver
> > specific headers in include/linux/platform_data. For omap1 we are not
> > planning common zImage support, so let's just make sure we're not
> > breaking anything there as people are still using it.
> 
> Hmm, so did I understand right, for omap1 stuff we can still include
> from arch/arm/mach-omap1/include/mach?

Yes that's a separate issue to fix that up for armv4/5 common
zImage support if people want to do that later on.
 
> If so, that makes things easier. I can manage the omap2+ stuff fine, but
> I have no experience with omap1, nor do I have any omap1 devices. So I'd
> rather keep the omap1 code as it is, in fear that I'd just break it
> totally, and I'd rather spend my time on omap2+ code.

Regards,

Tony


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks
@ 2012-09-06 20:08             ` Tony Lindgren
  0 siblings, 0 replies; 146+ messages in thread
From: Tony Lindgren @ 2012-09-06 20:08 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Chandrabhanu Mahapatra, paul, linux-omap, linux-fbdev

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120831 04:24]:
> On Thu, 2012-08-30 at 10:19 -0700, Tony Lindgren wrote:
> > Hi,
> > 
> > * Tomi Valkeinen <tomi.valkeinen@ti.com> [120830 00:35]:
> > > On Wed, 2012-08-29 at 17:20 -0700, Tony Lindgren wrote:
> > > > 
> > > > Good to see this, we need this badly to avoid blocking
> > > > single zImage effort on omaps. Can you also please take
> > > 
> > > What is the issue with single zImage? How do cpu_is_ check affect it?
> > 
> > The usage for that should only be limited to arch/arm/mach-omap2
> > so we can make cpu.h local as we can't include mach and plat
> > header files from the drivers with single zImage.
> 
> Ok.
> 
> > > $ git grep -E "<plat|<mach" drivers/video/omap*
> > > drivers/video/omap/lcd_ams_delta.c:#include <plat/board-ams-delta.h>
> > > * Needs to be moved
> > 
> > Yes, that should be either mach/board-ams-delta.h, or separate driver
> > specific headers in include/linux/platform_data. For omap1 we are not
> > planning common zImage support, so let's just make sure we're not
> > breaking anything there as people are still using it.
> 
> Hmm, so did I understand right, for omap1 stuff we can still include
> from arch/arm/mach-omap1/include/mach?

Yes that's a separate issue to fix that up for armv4/5 common
zImage support if people want to do that later on.
 
> If so, that makes things easier. I can manage the omap2+ stuff fine, but
> I have no experience with omap1, nor do I have any omap1 devices. So I'd
> rather keep the omap1 code as it is, in fear that I'd just break it
> totally, and I'd rather spend my time on omap2+ code.

Regards,

Tony


^ permalink raw reply	[flat|nested] 146+ messages in thread

end of thread, other threads:[~2012-09-06 20:08 UTC | newest]

Thread overview: 146+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-07  8:27 [PATCH 0/6] OMAPDSS: Remove cpu_is checks Chandrabhanu Mahapatra
2012-08-07  8:39 ` Chandrabhanu Mahapatra
2012-08-07  8:27 ` [PATCH 1/6] OMAPDSS: DISPC: Remove cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-07  8:39   ` Chandrabhanu Mahapatra
2012-08-07  8:48   ` Felipe Balbi
2012-08-07  8:48     ` Felipe Balbi
2012-08-07  9:05     ` Tomi Valkeinen
2012-08-07  9:05       ` Tomi Valkeinen
2012-08-07  9:14       ` Felipe Balbi
2012-08-07  9:14         ` Felipe Balbi
2012-08-07  9:27         ` Tomi Valkeinen
2012-08-07  9:27           ` Tomi Valkeinen
2012-08-07  9:32           ` Felipe Balbi
2012-08-07  9:32             ` Felipe Balbi
2012-08-07  9:57             ` Tomi Valkeinen
2012-08-07  9:57               ` Tomi Valkeinen
2012-08-07 10:27               ` Felipe Balbi
2012-08-07 10:27                 ` Felipe Balbi
2012-08-07 10:57                 ` Tomi Valkeinen
2012-08-07 10:57                   ` Tomi Valkeinen
2012-08-07 11:14                   ` Tony Lindgren
2012-08-07 11:14                     ` Tony Lindgren
2012-08-07 10:52   ` Tomi Valkeinen
2012-08-07 10:52     ` Tomi Valkeinen
2012-08-07 12:22     ` Chandrabhanu Mahapatra
2012-08-07 12:34       ` Chandrabhanu Mahapatra
2012-08-07 13:00       ` Tomi Valkeinen
2012-08-07 13:00         ` Tomi Valkeinen
2012-08-08 11:37   ` [PATCH 1/6] OMAPDSS: DISPC: cleanup " Chandrabhanu Mahapatra
2012-08-08 11:49     ` Chandrabhanu Mahapatra
2012-08-08 12:36     ` Tomi Valkeinen
2012-08-08 12:36       ` Tomi Valkeinen
2012-08-08 13:01       ` Mahapatra, Chandrabhanu
2012-08-08 13:13         ` Mahapatra, Chandrabhanu
2012-08-08 13:25         ` Tomi Valkeinen
2012-08-08 13:25           ` Tomi Valkeinen
2012-08-13 11:58     ` Chandrabhanu Mahapatra
2012-08-13 12:10       ` Chandrabhanu Mahapatra
2012-08-14  9:58       ` Tomi Valkeinen
2012-08-14  9:58         ` Tomi Valkeinen
2012-08-14 12:03       ` Mahapatra, Chandrabhanu
2012-08-14 12:15         ` Mahapatra, Chandrabhanu
2012-08-14 12:16         ` Tomi Valkeinen
2012-08-14 12:16           ` Tomi Valkeinen
2012-08-16 11:18       ` [PATCH V4 " Chandrabhanu Mahapatra
2012-08-16 11:30         ` Chandrabhanu Mahapatra
2012-08-07  8:27 ` [PATCH 2/6] OMAPDSS: DSS: Remove redundant functions Chandrabhanu Mahapatra
2012-08-07  8:39   ` Chandrabhanu Mahapatra
2012-08-07  8:28 ` [PATCH 3/6] OMAPDSS: DSS: Remove cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-07  8:40   ` Chandrabhanu Mahapatra
2012-08-07  8:49   ` Felipe Balbi
2012-08-07  8:49     ` Felipe Balbi
2012-08-07 13:14   ` Tomi Valkeinen
2012-08-07 13:14     ` Tomi Valkeinen
2012-08-08 11:38   ` [PATCH 3/6] OMAPDSS: DSS: Cleanup " Chandrabhanu Mahapatra
2012-08-08 11:50     ` Chandrabhanu Mahapatra
2012-08-08 13:16     ` Tomi Valkeinen
2012-08-08 13:16       ` Tomi Valkeinen
2012-08-09 11:39       ` Mahapatra, Chandrabhanu
2012-08-09 11:51         ` Mahapatra, Chandrabhanu
2012-08-13 11:59     ` Chandrabhanu Mahapatra
2012-08-13 12:11       ` Chandrabhanu Mahapatra
2012-08-14  9:48       ` Tomi Valkeinen
2012-08-14  9:48         ` Tomi Valkeinen
2012-08-14 12:30         ` Mahapatra, Chandrabhanu
2012-08-14 12:42           ` Mahapatra, Chandrabhanu
2012-08-14 14:34           ` Tomi Valkeinen
2012-08-14 14:34             ` Tomi Valkeinen
2012-08-16 11:18       ` [PATCH V4 " Chandrabhanu Mahapatra
2012-08-16 11:30         ` Chandrabhanu Mahapatra
2012-08-17 13:54         ` Tomi Valkeinen
2012-08-17 13:54           ` Tomi Valkeinen
2012-08-20  8:42           ` Tomi Valkeinen
2012-08-20  8:42             ` Tomi Valkeinen
2012-08-20 10:36             ` Mahapatra, Chandrabhanu
2012-08-20 10:48               ` Mahapatra, Chandrabhanu
2012-08-20 10:46               ` Tomi Valkeinen
2012-08-20 10:46                 ` Tomi Valkeinen
2012-08-07  8:28 ` [PATCH 4/6] OMAPDSS: VENC: Remove " Chandrabhanu Mahapatra
2012-08-07  8:40   ` Chandrabhanu Mahapatra
2012-08-07  8:51   ` Felipe Balbi
2012-08-07  8:51     ` Felipe Balbi
2012-08-07 12:36     ` Chandrabhanu Mahapatra
2012-08-07 12:48       ` Chandrabhanu Mahapatra
2012-08-07  8:28 ` [PATCH 5/6] ARM: OMAP: Disable venc for OMAP4 Chandrabhanu Mahapatra
2012-08-07  8:40   ` Chandrabhanu Mahapatra
2012-08-07  8:28   ` Chandrabhanu Mahapatra
2012-08-07  8:29 ` [PATCH 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-07  8:41   ` Chandrabhanu Mahapatra
2012-08-20 13:21 ` [PATCH V5 0/6] OMAPDSS: Cleanup cpu_is checks Chandrabhanu Mahapatra
2012-08-20 13:33   ` Chandrabhanu Mahapatra
2012-08-20 13:22   ` [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-20 13:34     ` Chandrabhanu Mahapatra
2012-08-21 10:31     ` Tomi Valkeinen
2012-08-21 10:31       ` Tomi Valkeinen
2012-08-21 11:20       ` Mahapatra, Chandrabhanu
2012-08-21 11:32         ` Mahapatra, Chandrabhanu
2012-08-20 13:23   ` [PATCH V5 2/6] OMAPDSS: DSS: Remove redundant functions Chandrabhanu Mahapatra
2012-08-20 13:35     ` Chandrabhanu Mahapatra
2012-08-20 13:23   ` [PATCH V5 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-20 13:35     ` Chandrabhanu Mahapatra
2012-08-21 10:35     ` Tomi Valkeinen
2012-08-21 10:35       ` Tomi Valkeinen
2012-08-21 11:06       ` Mahapatra, Chandrabhanu
2012-08-21 11:18         ` Mahapatra, Chandrabhanu
2012-08-21 11:20         ` Tomi Valkeinen
2012-08-21 11:20           ` Tomi Valkeinen
2012-08-20 13:24   ` [PATCH V5 4/6] OMAPDSS: VENC: Remove " Chandrabhanu Mahapatra
2012-08-20 13:36     ` Chandrabhanu Mahapatra
2012-08-20 13:24   ` [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4 Chandrabhanu Mahapatra
2012-08-20 13:36     ` Chandrabhanu Mahapatra
2012-08-21 10:32     ` Tomi Valkeinen
2012-08-21 10:32       ` Tomi Valkeinen
2012-08-21 11:13       ` Mahapatra, Chandrabhanu
2012-08-21 11:25         ` Mahapatra, Chandrabhanu
2012-08-20 13:24   ` [PATCH V5 6/6] OMAPDSS: DPI: Remove cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-20 13:36     ` Chandrabhanu Mahapatra
2012-08-22  6:36   ` [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks Chandrabhanu Mahapatra
2012-08-22  6:48     ` Chandrabhanu Mahapatra
2012-08-22  6:36     ` Chandrabhanu Mahapatra
2012-08-22  6:37     ` [PATCH V6 1/6] OMAPDSS: DISPC: Cleanup cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-22  6:49       ` Chandrabhanu Mahapatra
2012-08-22  6:37     ` [PATCH V6 2/6] OMAPDSS: DSS: Remove redundant functions Chandrabhanu Mahapatra
2012-08-22  6:49       ` Chandrabhanu Mahapatra
2012-08-22  6:38     ` [PATCH V6 3/6] OMAPDSS: DSS: Cleanup cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-22  6:50       ` Chandrabhanu Mahapatra
2012-08-22  6:38     ` [PATCH V6 4/6] ARM: OMAP: Disable venc for OMAP4 Chandrabhanu Mahapatra
2012-08-22  6:50       ` Chandrabhanu Mahapatra
2012-08-22  6:38       ` Chandrabhanu Mahapatra
2012-08-22  6:38     ` [PATCH V6 5/6] OMAPDSS: VENC: Remove cpu_is_xxxx checks Chandrabhanu Mahapatra
2012-08-22  6:50       ` Chandrabhanu Mahapatra
2012-08-22  6:39     ` [PATCH V6 6/6] OMAPDSS: DPI: " Chandrabhanu Mahapatra
2012-08-22  6:51       ` Chandrabhanu Mahapatra
2012-08-22  8:44     ` [PATCH V6 0/6] OMAPDSS: Cleanup cpu_is checks Tomi Valkeinen
2012-08-22  8:44       ` Tomi Valkeinen
2012-08-22  8:44       ` Tomi Valkeinen
2012-08-30  0:20   ` [PATCH V5 " Tony Lindgren
2012-08-30  0:20     ` Tony Lindgren
2012-08-30  7:34     ` Tomi Valkeinen
2012-08-30  7:34       ` Tomi Valkeinen
2012-08-30 17:19       ` Tony Lindgren
2012-08-30 17:19         ` Tony Lindgren
2012-08-31 11:23         ` Tomi Valkeinen
2012-08-31 11:23           ` Tomi Valkeinen
2012-09-06 20:08           ` Tony Lindgren
2012-09-06 20:08             ` Tony Lindgren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.