Skip to content

Commit

Permalink
OMAPDSS: DISPC: Update Scaling Clock Logic
Browse files Browse the repository at this point in the history
Clock requirements for scaling in OMAP2, OMAP3 and OMAP4 are different. In
OMAP2 and OMAP3 the required clock rate is a function of pixel clock, vertical
downscale ratio and horizontal downscale ratio whereas in OMAP4 it is a
function of pixel clock and horizontal downscale ratio only. Selection of 3-tap
vs 5-tap coefficients depends on clock rate line buffer width in OMAP3 whereas
in OMAP4 it is independent of clock rate and line buffer width. In OMAP2 3-tap
for vertical and 5-tap for horizontal scaling is used. In OMAP4 5-tap is used
both for horizontal and vertical scaling for better performance. Also, the
number and width of line buffers differs in OMAP3 and OMAP4.

So, clock functions have been fined tuned for OMAP3 and support has been added
added for OMAP4. This code has been tested on OMAP2, OMAP3 and OMAP4, and
scaling issues due to clock errors have been resolved.

Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
  • Loading branch information
Chandrabhanu Mahapatra authored and Tomi Valkeinen committed Jan 2, 2012
1 parent debd907 commit 7282f1b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 20 deletions.
66 changes: 46 additions & 20 deletions drivers/video/omap2/dss/dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,9 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
u32 fclk = 0;
u64 tmp, pclk = dispc_mgr_pclk_rate(channel);

if (height <= out_height && width <= out_width)
return (unsigned long) pclk;

if (height > out_height) {
struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
unsigned int ppl = dssdev->panel.timings.x_res;
Expand Down Expand Up @@ -1668,7 +1671,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
else
vf = 1;

return dispc_mgr_pclk_rate(channel) * vf * hf;
if (cpu_is_omap24xx()) {
if (vf > 1 && hf > 1)
return dispc_mgr_pclk_rate(channel) * 4;
else
return dispc_mgr_pclk_rate(channel) * 2;
} else if (cpu_is_omap34xx()) {
return dispc_mgr_pclk_rate(channel) * vf * hf;
} else {
return dispc_mgr_pclk_rate(channel) * hf;
}
}

static int dispc_ovl_calc_scaling(enum omap_plane plane,
Expand All @@ -1678,6 +1690,8 @@ 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);
unsigned long fclk = 0;

if (width == out_width && height == out_height)
Expand All @@ -1694,28 +1708,40 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
out_height > height * 8)
return -EINVAL;

/* Must use 5-tap filter? */
*five_taps = height > out_height * 2;

if (!*five_taps) {
if (cpu_is_omap24xx()) {
if (width > maxsinglelinewidth)
DSSERR("Cannot scale max input width exceeded");
*five_taps = false;
fclk = calc_fclk(channel, width, height, out_width,
out_height);
} else if (cpu_is_omap34xx()) {
if (width > (maxsinglelinewidth * 2)) {
DSSERR("Cannot setup scaling");
DSSERR("width exceeds maximum width possible");
return -EINVAL;
}
fclk = calc_fclk_five_taps(channel, width, height, out_width,
out_height, color_mode);
if (width > maxsinglelinewidth) {
if (height > out_height && height < out_height * 2)
*five_taps = false;
else {
DSSERR("cannot setup scaling with five taps");
return -EINVAL;
}
}
if (!*five_taps)
fclk = calc_fclk(channel, width, height, out_width,
out_height);
} else {
if (width > maxsinglelinewidth) {
DSSERR("Cannot scale width exceeds max line width");
return -EINVAL;
}
fclk = calc_fclk(channel, width, height, out_width,
out_height);

/* Try 5-tap filter if 3-tap fclk is too high */
if (cpu_is_omap34xx() && height > out_height &&
fclk > dispc_fclk_rate())
*five_taps = true;
}

if (width > (2048 >> *five_taps)) {
DSSERR("failed to set up scaling, fclk too low\n");
return -EINVAL;
}

if (*five_taps)
fclk = calc_fclk_five_taps(channel, width, height,
out_width, out_height, color_mode);

DSSDBG("required fclk rate = %lu Hz\n", fclk);
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());

Expand All @@ -1734,7 +1760,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
bool ilace, bool replication)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
bool five_taps = false;
bool five_taps = true;
bool fieldmode = 0;
int r, cconv = 0;
unsigned offset0, offset1;
Expand Down
7 changes: 7 additions & 0 deletions drivers/video/omap2/dss/dss_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
/*
* Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
* scaler cannot scale a image with width more than 768.
*/
[FEAT_PARAM_LINEWIDTH] = { 1, 768 },
};

static const struct dss_param_range omap3_dss_param_range[] = {
Expand All @@ -316,6 +321,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
};

static const struct dss_param_range omap4_dss_param_range[] = {
Expand All @@ -328,6 +334,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
};

/* OMAP2 DSS Features */
Expand Down
1 change: 1 addition & 0 deletions drivers/video/omap2/dss/dss_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum dss_range_param {
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
FEAT_PARAM_DOWNSCALE,
FEAT_PARAM_LINEWIDTH,
};

/* DSS Feature Functions */
Expand Down

0 comments on commit 7282f1b

Please sign in to comment.