Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 251091
b: refs/heads/master
c: 0d66cbb
h: refs/heads/master
i:
  251089: 5362210
  251087: 676d366
v: v3
  • Loading branch information
Amber Jain authored and Tomi Valkeinen committed May 23, 2011
1 parent 5f40af3 commit 6605c66
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ab5ca071e231e6d6da5f6aa9484a2cd233f7c746
refs/heads/master: 0d66cbb53eca4ab3db85d9189d5a85c9fac49b84
201 changes: 169 additions & 32 deletions trunk/drivers/video/omap2/dss/dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ static struct {
#endif
} dispc;

enum omap_color_component {
/* used for all color formats for OMAP3 and earlier
* and for RGB and Y color component on OMAP4
*/
DISPC_COLOR_COMPONENT_RGB_Y = 1 << 0,
/* used for UV component for
* OMAP_DSS_COLOR_YUV2, OMAP_DSS_COLOR_UYVY, OMAP_DSS_COLOR_NV12
* color formats on OMAP4
*/
DISPC_COLOR_COMPONENT_UV = 1 << 1,
};

static void _omap_dispc_set_irqs(void);

static inline void dispc_write_reg(const u16 idx, u32 val)
Expand Down Expand Up @@ -574,7 +586,8 @@ static void _dispc_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
}

static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
int vscaleup, int five_taps)
int vscaleup, int five_taps,
enum omap_color_component color_comp)
{
/* Coefficients for horizontal up-sampling */
static const struct dispc_h_coef coef_hup[8] = {
Expand Down Expand Up @@ -672,16 +685,25 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
| FLD_VAL(v_coef[i].vc1, 23, 16)
| FLD_VAL(v_coef[i].vc2, 31, 24);

_dispc_write_firh_reg(plane, i, h);
_dispc_write_firhv_reg(plane, i, hv);
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
_dispc_write_firh_reg(plane, i, h);
_dispc_write_firhv_reg(plane, i, hv);
} else {
_dispc_write_firh2_reg(plane, i, h);
_dispc_write_firhv2_reg(plane, i, hv);
}

}

if (five_taps) {
for (i = 0; i < 8; i++) {
u32 v;
v = FLD_VAL(v_coef[i].vc00, 7, 0)
| FLD_VAL(v_coef[i].vc22, 15, 8);
_dispc_write_firv_reg(plane, i, v);
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y)
_dispc_write_firv_reg(plane, i, v);
else
_dispc_write_firv2_reg(plane, i, v);
}
}
}
Expand Down Expand Up @@ -1090,18 +1112,27 @@ void dispc_enable_fifomerge(bool enable)
enable_clocks(0);
}

static void _dispc_set_fir(enum omap_plane plane, int hinc, int vinc)
static void _dispc_set_fir(enum omap_plane plane,
int hinc, int vinc,
enum omap_color_component color_comp)
{
u32 val;
u8 hinc_start, hinc_end, vinc_start, vinc_end;

dss_feat_get_reg_field(FEAT_REG_FIRHINC, &hinc_start, &hinc_end);
dss_feat_get_reg_field(FEAT_REG_FIRVINC, &vinc_start, &vinc_end);
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
u8 hinc_start, hinc_end, vinc_start, vinc_end;

val = FLD_VAL(vinc, vinc_start, vinc_end) |
FLD_VAL(hinc, hinc_start, hinc_end);
dss_feat_get_reg_field(FEAT_REG_FIRHINC,
&hinc_start, &hinc_end);
dss_feat_get_reg_field(FEAT_REG_FIRVINC,
&vinc_start, &vinc_end);
val = FLD_VAL(vinc, vinc_start, vinc_end) |
FLD_VAL(hinc, hinc_start, hinc_end);

dispc_write_reg(DISPC_OVL_FIR(plane), val);
dispc_write_reg(DISPC_OVL_FIR(plane), val);
} else {
val = FLD_VAL(vinc, 28, 16) | FLD_VAL(hinc, 12, 0);
dispc_write_reg(DISPC_OVL_FIR2(plane), val);
}
}

static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
Expand Down Expand Up @@ -1148,31 +1179,40 @@ static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu)
dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val);
}

static void _dispc_set_scaling(enum omap_plane plane,
static void _dispc_set_scale_param(enum omap_plane plane,
u16 orig_width, u16 orig_height,
u16 out_width, u16 out_height,
bool ilace, bool five_taps,
bool fieldmode)
bool five_taps, u8 rotation,
enum omap_color_component color_comp)
{
int fir_hinc;
int fir_vinc;
int fir_hinc, fir_vinc;
int hscaleup, vscaleup;
int accu0 = 0;
int accu1 = 0;
u32 l;

BUG_ON(plane == OMAP_DSS_GFX);

hscaleup = orig_width <= out_width;
vscaleup = orig_height <= out_height;

_dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps);
_dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps, color_comp);

fir_hinc = 1024 * orig_width / out_width;
fir_vinc = 1024 * orig_height / out_height;

_dispc_set_fir(plane, fir_hinc, fir_vinc);
_dispc_set_fir(plane, fir_hinc, fir_vinc, color_comp);
}

static void _dispc_set_scaling_common(enum omap_plane plane,
u16 orig_width, u16 orig_height,
u16 out_width, u16 out_height,
bool ilace, bool five_taps,
bool fieldmode, enum omap_color_mode color_mode,
u8 rotation)
{
int accu0 = 0;
int accu1 = 0;
u32 l;

_dispc_set_scale_param(plane, orig_width, orig_height,
out_width, out_height, five_taps,
rotation, DISPC_COLOR_COMPONENT_RGB_Y);
l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));

/* RESIZEENABLE and VERTICALTAPS */
Expand All @@ -1184,8 +1224,8 @@ static void _dispc_set_scaling(enum omap_plane plane,
/* VRESIZECONF and HRESIZECONF */
if (dss_has_feature(FEAT_RESIZECONF)) {
l &= ~(0x3 << 7);
l |= hscaleup ? 0 : (1 << 7);
l |= vscaleup ? 0 : (1 << 8);
l |= (orig_width <= out_width) ? 0 : (1 << 7);
l |= (orig_height <= out_height) ? 0 : (1 << 8);
}

/* LINEBUFFERSPLIT */
Expand All @@ -1202,7 +1242,7 @@ static void _dispc_set_scaling(enum omap_plane plane,
*/
if (ilace && !fieldmode) {
accu1 = 0;
accu0 = (fir_vinc / 2) & 0x3ff;
accu0 = ((1024 * orig_height / out_height) / 2) & 0x3ff;
if (accu0 >= 1024/2) {
accu1 = 1024/2;
accu0 -= accu1;
Expand All @@ -1213,6 +1253,93 @@ static void _dispc_set_scaling(enum omap_plane plane,
_dispc_set_vid_accu1(plane, 0, accu1);
}

static void _dispc_set_scaling_uv(enum omap_plane plane,
u16 orig_width, u16 orig_height,
u16 out_width, u16 out_height,
bool ilace, bool five_taps,
bool fieldmode, enum omap_color_mode color_mode,
u8 rotation)
{
int scale_x = out_width != orig_width;
int scale_y = out_height != orig_height;

if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
if ((color_mode != OMAP_DSS_COLOR_YUV2 &&
color_mode != OMAP_DSS_COLOR_UYVY &&
color_mode != OMAP_DSS_COLOR_NV12)) {
/* reset chroma resampling for RGB formats */
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
return;
}
switch (color_mode) {
case OMAP_DSS_COLOR_NV12:
/* UV is subsampled by 2 vertically*/
orig_height >>= 1;
/* UV is subsampled by 2 horz.*/
orig_width >>= 1;
break;
case OMAP_DSS_COLOR_YUV2:
case OMAP_DSS_COLOR_UYVY:
/*For YUV422 with 90/270 rotation,
*we don't upsample chroma
*/
if (rotation == OMAP_DSS_ROT_0 ||
rotation == OMAP_DSS_ROT_180)
/* UV is subsampled by 2 hrz*/
orig_width >>= 1;
/* must use FIR for YUV422 if rotated */
if (rotation != OMAP_DSS_ROT_0)
scale_x = scale_y = true;
break;
default:
BUG();
}

if (out_width != orig_width)
scale_x = true;
if (out_height != orig_height)
scale_y = true;

_dispc_set_scale_param(plane, orig_width, orig_height,
out_width, out_height, five_taps,
rotation, DISPC_COLOR_COMPONENT_UV);

REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
(scale_x || scale_y) ? 1 : 0, 8, 8);
/* set H scaling */
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
/* set V scaling */
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6);

_dispc_set_vid_accu2_0(plane, 0x80, 0);
_dispc_set_vid_accu2_1(plane, 0x80, 0);
}

static void _dispc_set_scaling(enum omap_plane plane,
u16 orig_width, u16 orig_height,
u16 out_width, u16 out_height,
bool ilace, bool five_taps,
bool fieldmode, enum omap_color_mode color_mode,
u8 rotation)
{
BUG_ON(plane == OMAP_DSS_GFX);

_dispc_set_scaling_common(plane,
orig_width, orig_height,
out_width, out_height,
ilace, five_taps,
fieldmode, color_mode,
rotation);

_dispc_set_scaling_uv(plane,
orig_width, orig_height,
out_width, out_height,
ilace, five_taps,
fieldmode, color_mode,
rotation);
}

static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
bool mirroring, enum omap_color_mode color_mode)
{
Expand Down Expand Up @@ -1619,7 +1746,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
enum omap_dss_rotation_type rotation_type,
u8 rotation, int mirror,
u8 global_alpha, u8 pre_mult_alpha,
enum omap_channel channel)
enum omap_channel channel, u32 puv_addr)
{
const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
bool five_taps = 0;
Expand Down Expand Up @@ -1668,7 +1795,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
return -EINVAL;

if (color_mode == OMAP_DSS_COLOR_YUV2 ||
color_mode == OMAP_DSS_COLOR_UYVY)
color_mode == OMAP_DSS_COLOR_UYVY ||
color_mode == OMAP_DSS_COLOR_NV12)
cconv = 1;

/* Must use 5-tap filter? */
Expand Down Expand Up @@ -1742,6 +1870,12 @@ static int _dispc_setup_plane(enum omap_plane plane,
_dispc_set_plane_ba0(plane, paddr + offset0);
_dispc_set_plane_ba1(plane, paddr + offset1);

if (OMAP_DSS_COLOR_NV12 == color_mode) {
_dispc_set_plane_ba0_uv(plane, puv_addr + offset0);
_dispc_set_plane_ba1_uv(plane, puv_addr + offset1);
}


_dispc_set_row_inc(plane, row_inc);
_dispc_set_pix_inc(plane, pix_inc);

Expand All @@ -1755,7 +1889,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
if (plane != OMAP_DSS_GFX) {
_dispc_set_scaling(plane, width, height,
out_width, out_height,
ilace, five_taps, fieldmode);
ilace, five_taps, fieldmode,
color_mode, rotation);
_dispc_set_vid_size(plane, out_width, out_height);
_dispc_set_vid_color_conv(plane, cconv);
}
Expand Down Expand Up @@ -3439,11 +3574,12 @@ int dispc_setup_plane(enum omap_plane plane,
bool ilace,
enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror, u8 global_alpha,
u8 pre_mult_alpha, enum omap_channel channel)
u8 pre_mult_alpha, enum omap_channel channel,
u32 puv_addr)
{
int r = 0;

DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d, %d, %dx%d -> "
"%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
plane, paddr, screen_width, pos_x, pos_y,
width, height,
Expand All @@ -3462,7 +3598,8 @@ int dispc_setup_plane(enum omap_plane plane,
rotation_type,
rotation, mirror,
global_alpha,
pre_mult_alpha, channel);
pre_mult_alpha,
channel, puv_addr);

enable_clocks(0);

Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/video/omap2/dss/dss.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ int dispc_setup_plane(enum omap_plane plane,
enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror,
u8 global_alpha, u8 pre_mult_alpha,
enum omap_channel channel);
enum omap_channel channel,
u32 puv_addr);

bool dispc_go_busy(enum omap_channel channel);
void dispc_go(enum omap_channel channel);
Expand Down
5 changes: 4 additions & 1 deletion trunk/drivers/video/omap2/dss/manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ struct overlay_cache_data {

u32 paddr;
void __iomem *vaddr;
u32 p_uv_addr; /* relevant for NV12 format only */
u16 screen_width;
u16 width;
u16 height;
Expand Down Expand Up @@ -861,7 +862,8 @@ static int configure_overlay(enum omap_plane plane)
c->mirror,
c->global_alpha,
c->pre_mult_alpha,
c->channel);
c->channel,
c->p_uv_addr);

if (r) {
/* this shouldn't happen */
Expand Down Expand Up @@ -1276,6 +1278,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)

oc->paddr = ovl->info.paddr;
oc->vaddr = ovl->info.vaddr;
oc->p_uv_addr = ovl->info.p_uv_addr;
oc->screen_width = ovl->info.screen_width;
oc->width = ovl->info.width;
oc->height = ovl->info.height;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/video/omapdss.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ struct omap_overlay_info {

u32 paddr;
void __iomem *vaddr;
u32 p_uv_addr; /* for NV12 format */
u16 screen_width;
u16 width;
u16 height;
Expand Down

0 comments on commit 6605c66

Please sign in to comment.